提交代码
This commit is contained in:
parent
e081d46f0d
commit
a5c5fc72db
|
|
@ -1,9 +1,12 @@
|
|||
using Bogus.DataSets;
|
||||
|
||||
using CloudGaming.Api.Base;
|
||||
using CloudGaming.Code.Account;
|
||||
using CloudGaming.Code.AppExtend;
|
||||
using CloudGaming.Code.DataAccess;
|
||||
using CloudGaming.Code.MiddlewareExtend;
|
||||
using CloudGaming.DtoModel.Account;
|
||||
using CloudGaming.DtoModel.Account.Login;
|
||||
using CloudGaming.GameModel.Db.Db_Ext;
|
||||
|
||||
using HuanMeng.DotNetCore.AttributeExtend;
|
||||
|
|
@ -11,6 +14,7 @@ using HuanMeng.DotNetCore.Base;
|
|||
|
||||
using HuanMeng.DotNetCore.Utility;
|
||||
|
||||
using Microsoft.AspNetCore.Authorization;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace CloudGaming.Api.Controllers;
|
||||
|
|
@ -36,4 +40,29 @@ public class AccountController : CloudGamingControllerBase
|
|||
AccountBLL account = new AccountBLL(ServiceProvider);
|
||||
return await account.SendPhoneNumber(phoneNumber.PhoneNumber);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登录接口
|
||||
/// 登录数据格式(设备号的目的是用于以后的多设备登录)
|
||||
/// 短信登录:{"phoneNumber":"手机号","verificationCode":"验证码","deviceNumber":"设备号"}
|
||||
/// token登录(请求标头需要带上Authorized的token) {"deviceNumber":"设备号"}
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost]
|
||||
public async Task<AccountLogInResponse> LoginAsync([FromBody] BaseLoginParams baseLogin)
|
||||
{
|
||||
AccountBLL account = new AccountBLL(ServiceProvider);
|
||||
return await account.LoginAsync();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpGet]
|
||||
[Authorize]
|
||||
public async Task<bool> GetUserInfo()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,10 +1,20 @@
|
|||
using CloudGaming.Code.Sms;
|
||||
using Alipay.EasySDK.Kernel;
|
||||
|
||||
using CloudGaming.Code.Account.Contract;
|
||||
using CloudGaming.Code.Sms;
|
||||
using CloudGaming.DtoModel.Account;
|
||||
using CloudGaming.DtoModel.Account.Login;
|
||||
|
||||
using HuanMeng.DotNetCore.JwtInfrastructure;
|
||||
using HuanMeng.DotNetCore.Redis;
|
||||
using HuanMeng.DotNetCore.Utility;
|
||||
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
|
@ -29,13 +39,13 @@ namespace CloudGaming.Code.Account
|
|||
{
|
||||
if (!PhoneNumberValidator.IsPhoneNumber(PhoneNumber))
|
||||
{
|
||||
throw new MessageException(ResonseCode.PhoneNumberException, "手机号格式错误");
|
||||
throw MessageBox.Show(ResonseCode.PhoneNumberException, "手机号格式错误");
|
||||
}
|
||||
var day = int.Parse(DateTime.Now.ToString("yyyyMMdd"));
|
||||
var smsCount = await Dao.DaoExt.Context.T_Sms_Log.Where(it => it.SendTimeDay == day && it.PhoneNumber == PhoneNumber).CountAsync();
|
||||
if (smsCount >= 5)
|
||||
{
|
||||
throw new MessageException(ResonseCode.PhoneNumberMaxException, "当日发送以达到上限");
|
||||
throw MessageBox.Show(ResonseCode.PhoneNumberMaxException, "当日发送以达到上限");
|
||||
}
|
||||
var phoneNumberCache = RedisCache.StringGetAsync($"App:sms:{PhoneNumber}");
|
||||
var verificationCode = new Random().Next(1000, 9999).ToString();
|
||||
|
|
@ -59,6 +69,7 @@ namespace CloudGaming.Code.Account
|
|||
{
|
||||
await RedisCache.StringSetAsync($"App:sms:{PhoneNumber}", verificationCode, TimeSpan.FromMinutes(5));
|
||||
}
|
||||
|
||||
T_Sms_Log t_Sms_Log = new T_Sms_Log()
|
||||
{
|
||||
VerificationCode = verificationCode,
|
||||
|
|
@ -70,7 +81,214 @@ namespace CloudGaming.Code.Account
|
|||
};
|
||||
Dao.DaoExt.Context.T_Sms_Log.Add(t_Sms_Log);
|
||||
await Dao.DaoExt.Context.SaveChangesAsync();
|
||||
if (!isSend)
|
||||
{
|
||||
throw MessageBox.ErrorShow("发送失败");
|
||||
}
|
||||
return isSend;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 登录接口
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public async Task<AccountLogInResponse> LoginAsync()
|
||||
{
|
||||
this.HttpContextAccessor.HttpContext.Request.Body.Position = 0;
|
||||
var json = await new StreamReader(this.HttpContextAccessor.HttpContext.Request.Body).ReadToEndAsync();
|
||||
if (string.IsNullOrEmpty(json))
|
||||
{
|
||||
throw MessageBox.Show(ResonseCode.NullOrEmpty, "登录方式不合格");
|
||||
}
|
||||
|
||||
var account = AccountExtend.GetUserAccount(json, this);
|
||||
if (account == null)
|
||||
{
|
||||
throw MessageBox.Show(ResonseCode.NullOrEmpty, "未找到登录方式");
|
||||
}
|
||||
|
||||
var userId = await account.LoginAsync();
|
||||
bool isNew = false;
|
||||
if (userId == 0)
|
||||
{
|
||||
isNew = true;
|
||||
}
|
||||
var ip = this.HttpContextAccessor.HttpContext.GetClientIpAddress();
|
||||
//登录或者注册用户
|
||||
var user = await RegisterOrUpdateUserAsync(userId, account, ip);
|
||||
//注册用户详细信息
|
||||
var userData = await EnsureUserDataExistsAsync(user.Id, account);
|
||||
//创建jwt登录
|
||||
var jwt = GenerateJwtToken(user);
|
||||
var accountLogIn = new AccountLogInResponse
|
||||
{
|
||||
NickName = user.NickName,
|
||||
Token = jwt.AccessToken,
|
||||
UserId = user.Id,
|
||||
};
|
||||
//创建设备号
|
||||
var dev = await ManageUserDevicesAsync(user, account, jwt.AccessToken);
|
||||
var key = $"user:login:{user.Id}";
|
||||
var accountUserLoginInfos = await RedisCache.StringGetAsync<List<AccountUserLoginInfo>>(key);
|
||||
accountUserLoginInfos ??= new List<AccountUserLoginInfo>();
|
||||
//创建redis缓存
|
||||
await RedisCache.StringSetAsync(key, $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}", TimeSpan.FromHours(1));
|
||||
//accountUserLoginInfos.Add(new AccountUserLoginInfo());
|
||||
T_User_Login_Log login_Log = new T_User_Login_Log()
|
||||
{
|
||||
Channel = this.AppRequestInfo.Channel,
|
||||
CreateTime = DateTime.Now,
|
||||
CreateTimeDay = 0,
|
||||
CreateTimeHour = 0,
|
||||
AppVersion = this.AppRequestInfo.Version,
|
||||
Ip = ip,
|
||||
IsNew = isNew,
|
||||
LoginType = account.LastLoginType,
|
||||
PlatformType = this.AppRequestInfo.Platform,
|
||||
UserId = user.Id,
|
||||
};
|
||||
await Dao.DaoExt.Context.AddAsync(login_Log);
|
||||
await Dao.DaoExt.Context.SaveChangesAsync();
|
||||
return accountLogIn;
|
||||
}
|
||||
#region 注册用户
|
||||
/// <summary>
|
||||
/// 注册新用户或更新现有用户信息
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="account"></param>
|
||||
/// <param name="ip"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<T_User> RegisterOrUpdateUserAsync(int userId, IUserAccount account, string ip)
|
||||
{
|
||||
var user = userId > 0
|
||||
? await Dao.DaoUser.Context.T_User.FirstOrDefaultAsync(it => it.Id == userId)
|
||||
: null;
|
||||
if (user == null)
|
||||
{
|
||||
user = new T_User
|
||||
{
|
||||
CreatedAt = DateTime.Now,
|
||||
LastLoginAt = DateTime.Now,
|
||||
UpdatedAt = DateTime.Now,
|
||||
IsTest = false,
|
||||
LastLoginType = account.LastLoginType,
|
||||
RegisterType = account.LastLoginType,
|
||||
State = 0,
|
||||
UserIconUrl = AppConfig.UserConfig.UserIconUrl,
|
||||
NickName = $"{AppConfig.UserConfig.NickName}{new Random().Next(1000, 9999)}",
|
||||
Ip = ip
|
||||
};
|
||||
await Dao.DaoUser.Context.T_User.AddAsync(user);
|
||||
}
|
||||
|
||||
user.LastLoginAt = DateTime.Now;
|
||||
user.UpdatedAt = DateTime.Now;
|
||||
user.Ip = ip;
|
||||
await Dao.DaoUser.Context.SaveChangesAsync();
|
||||
return user;
|
||||
}
|
||||
|
||||
// 确保用户数据存在
|
||||
private async Task<T_User_Data> EnsureUserDataExistsAsync(int userId, IUserAccount account)
|
||||
{
|
||||
var userData = await Dao.DaoUser.Context.T_User_Data.FirstOrDefaultAsync(it => it.UserId == userId);
|
||||
if (userData == null)
|
||||
{
|
||||
userData = new T_User_Data
|
||||
{
|
||||
CreateAt = DateTime.Now,
|
||||
UpdateAt = DateTime.Now,
|
||||
PhoneNum = account.GetUserDataProperty(UserDataPropertyEnum.PhoneNum),
|
||||
UserId = userId,
|
||||
Email = account.GetUserDataProperty(UserDataPropertyEnum.Email)
|
||||
};
|
||||
await Dao.DaoUser.Context.T_User_Data.AddAsync(userData);
|
||||
await Dao.DaoUser.Context.SaveChangesAsync();
|
||||
}
|
||||
return userData;
|
||||
}
|
||||
|
||||
// 生成JWT令牌
|
||||
private JwtAuthResult GenerateJwtToken(T_User user)
|
||||
{
|
||||
var claims = new[]
|
||||
{
|
||||
new Claim("NickName", user.NickName),
|
||||
new Claim("UserId", user.Id.ToString()),
|
||||
};
|
||||
return JwtAuthManager.GenerateTokens(user.NickName, claims, DateTime.Now);
|
||||
}
|
||||
|
||||
// 管理用户设备
|
||||
private async Task<T_User_Token> ManageUserDevicesAsync(T_User user, IUserAccount account, string accessToken)
|
||||
{
|
||||
var currentTime = DateTime.Now;
|
||||
var dev = string.IsNullOrEmpty(account.DeviceNumber)
|
||||
? MD5Encryption.ComputeMD5Hash($"{user.Id}:{account.LastLoginType}")
|
||||
: account.DeviceNumber;
|
||||
|
||||
var userLoginList = await Dao.DaoUser.Context.T_User_Token
|
||||
.Where(it => it.UserId == user.Id)
|
||||
.OrderBy(it => it.LastLoginAt)
|
||||
.ToListAsync();
|
||||
|
||||
// 删除多余的设备记录
|
||||
if (userLoginList.Count > AppConfig.UserConfig.MaxDeviceCount)
|
||||
{
|
||||
var excessDevices = userLoginList.Take(userLoginList.Count - AppConfig.UserConfig.MaxDeviceCount).ToList();
|
||||
Dao.DaoUser.Context.T_User_Token.RemoveRange(excessDevices);
|
||||
await Dao.DaoUser.Context.SaveChangesAsync();
|
||||
}
|
||||
|
||||
var existingDevice = userLoginList.FirstOrDefault(it => it.DeviceNumber == dev);
|
||||
|
||||
if (existingDevice == null)
|
||||
{
|
||||
if (userLoginList.Count == AppConfig.UserConfig.MaxDeviceCount)
|
||||
{
|
||||
// 替换最早登录的设备
|
||||
existingDevice = userLoginList.First();
|
||||
UpdateDeviceToken(existingDevice, dev, accessToken, currentTime);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 新增设备记录
|
||||
existingDevice = new T_User_Token
|
||||
{
|
||||
CreateAt = currentTime,
|
||||
ExpiresAt = currentTime.AddDays(5),
|
||||
LastLoginAt = currentTime,
|
||||
Token = accessToken,
|
||||
UserId = user.Id,
|
||||
DeviceNumber = dev,
|
||||
TokenMd5 = MD5Encryption.ComputeMD5Hash(accessToken)
|
||||
};
|
||||
await Dao.DaoUser.Context.T_User_Token.AddAsync(existingDevice);
|
||||
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 更新现有设备信息
|
||||
UpdateDeviceToken(existingDevice, dev, accessToken, currentTime);
|
||||
}
|
||||
|
||||
await Dao.DaoUser.Context.SaveChangesAsync();
|
||||
return existingDevice;
|
||||
}
|
||||
|
||||
// 更新设备令牌信息
|
||||
private void UpdateDeviceToken(T_User_Token device, string deviceNumber, string accessToken, DateTime currentTime)
|
||||
{
|
||||
device.DeviceNumber = deviceNumber;
|
||||
device.TokenMd5 = MD5Encryption.ComputeMD5Hash(accessToken);
|
||||
device.LastLoginAt = currentTime;
|
||||
device.ExpiresAt = currentTime.AddDays(5);
|
||||
device.Token = accessToken;
|
||||
}
|
||||
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,42 @@
|
|||
using CloudGaming.Code.Account.Contract;
|
||||
using CloudGaming.Code.Account.Login;
|
||||
using CloudGaming.DtoModel.Account.Login;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.Code.Account
|
||||
{
|
||||
public static class AccountExtend
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 返回对应的登录方式
|
||||
/// </summary>
|
||||
/// <param name="jsonString"></param>
|
||||
/// <returns></returns>
|
||||
public static IUserAccount? GetUserAccount(string jsonString, CloudGamingBase cloudGamingBase)
|
||||
{
|
||||
JObject jsonObject = JObject.Parse(jsonString);
|
||||
if (AllKeysExistIgnoreCase(jsonObject, "PhoneNumber", "VerificationCode"))
|
||||
{
|
||||
var loginParams = JsonConvert.DeserializeObject<PhoneLoginParams>(jsonString);
|
||||
PhoneUserLogin phoneUserLogin = new PhoneUserLogin(loginParams, cloudGamingBase);
|
||||
return phoneUserLogin;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
static bool AllKeysExistIgnoreCase(JObject jsonObject, params string[] keysToCheck)
|
||||
{
|
||||
var propertie = jsonObject.Properties();
|
||||
return keysToCheck.All(key => propertie.Any(p => string.Equals(p.Name, key, StringComparison.OrdinalIgnoreCase)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
using CloudGaming.DtoModel.Account;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.Code.Account.Contract
|
||||
{
|
||||
/// <summary>
|
||||
/// 登录接口
|
||||
/// </summary>
|
||||
public interface IUserAccount
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// 登录方式
|
||||
/// </summary>
|
||||
public int LastLoginType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备号
|
||||
/// </summary>
|
||||
public string DeviceNumber { get; }
|
||||
/// <summary>
|
||||
/// 登录
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
Task<int> LoginAsync();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 创建账号
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
Task CreateLoginAsync(T_User user);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取用户属性
|
||||
/// </summary>
|
||||
/// <param name="userDataPropertyEnum"></param>
|
||||
/// <returns></returns>
|
||||
string GetUserDataProperty(UserDataPropertyEnum userDataPropertyEnum);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
|
||||
|
||||
using Bogus.DataSets;
|
||||
|
||||
using CloudGaming.Code.Account.Contract;
|
||||
using CloudGaming.DtoModel.Account;
|
||||
using CloudGaming.DtoModel.Account.Login;
|
||||
|
||||
using HuanMeng.DotNetCore.Redis;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.Code.Account.Login
|
||||
{
|
||||
/// <summary>
|
||||
/// 手机号登录
|
||||
/// </summary>
|
||||
/// <param name="loginParams"></param>
|
||||
/// <param name="cloudGamingBase"></param>
|
||||
public class PhoneUserLogin(PhoneLoginParams loginParams, CloudGamingBase cloudGamingBase) : IUserAccount
|
||||
{
|
||||
public async Task<int> LoginAsync()
|
||||
{
|
||||
if (string.IsNullOrEmpty(loginParams.PhoneNumber))
|
||||
{
|
||||
throw MessageBox.Show(ResonseCode.ParamError, "手机号不能为空");
|
||||
}
|
||||
if (string.IsNullOrEmpty(loginParams.VerificationCode))
|
||||
{
|
||||
throw MessageBox.Show(ResonseCode.ParamError, "验证码不能为空");
|
||||
}
|
||||
//判断是否是测试账号
|
||||
if (!loginParams.PhoneNumber.Contains("999999999") && loginParams.VerificationCode == "1112")
|
||||
{
|
||||
if (!PhoneNumberValidator.IsPhoneNumber(loginParams.PhoneNumber))
|
||||
{
|
||||
throw MessageBox.Show(ResonseCode.PhoneNumberException, "手机号格式错误");
|
||||
}
|
||||
var verificationCodeRedis = await cloudGamingBase.RedisCache.StringGetAsync($"App:sms:{loginParams.PhoneNumber}");
|
||||
if (verificationCodeRedis.IsNullOrEmpty)
|
||||
{
|
||||
throw MessageBox.Show(ResonseCode.ParamError, "验证码已过期,请重新发送!");
|
||||
}
|
||||
var verificationCode = (string)verificationCodeRedis;
|
||||
if (verificationCode != loginParams.VerificationCode)
|
||||
{
|
||||
throw MessageBox.Show(ResonseCode.ParamError, "验证码错误!");
|
||||
}
|
||||
await cloudGamingBase.RedisCache.KeyDeleteAsync($"App:sms:{loginParams.PhoneNumber}");
|
||||
}
|
||||
|
||||
var userAccount = await cloudGamingBase.Dao.DaoUser.Context.T_User_Phone_Account.AsNoTracking().Where(it => it.PhoneNum == loginParams.PhoneNumber && !it.IsLogout).FirstOrDefaultAsync();
|
||||
return userAccount?.UserId ?? 0;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 创建登录账号
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <returns></returns>
|
||||
public async Task CreateLoginAsync(T_User user)
|
||||
{
|
||||
|
||||
T_User_Phone_Account t_User_Phone_Account = new T_User_Phone_Account()
|
||||
{
|
||||
UserId = user.Id,
|
||||
IsLogout = false,
|
||||
NikeName = user.NickName,
|
||||
PhoneNum = loginParams.PhoneNumber,
|
||||
UpdatedAt = DateTime.Now,
|
||||
CreatedAt = DateTime.Now,
|
||||
};
|
||||
await cloudGamingBase.Dao.DaoUser.Context.T_User_Phone_Account.AddAsync(t_User_Phone_Account);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public int LastLoginType { get; set; } = 1;
|
||||
|
||||
/// <summary>
|
||||
/// 返回登录信息
|
||||
/// </summary>
|
||||
/// <param name="userDataPropertyEnum"></param>
|
||||
/// <returns></returns>
|
||||
public string GetUserDataProperty(UserDataPropertyEnum userDataPropertyEnum)
|
||||
{
|
||||
if (userDataPropertyEnum == UserDataPropertyEnum.PhoneNum)
|
||||
{
|
||||
return loginParams.PhoneNumber;
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 设备号
|
||||
/// </summary>
|
||||
public string DeviceNumber
|
||||
{
|
||||
get
|
||||
{
|
||||
if (loginParams.DeviceNumber.Length > 100)
|
||||
{
|
||||
loginParams.DeviceNumber = loginParams.DeviceNumber.Substring(0, 100);
|
||||
}
|
||||
return loginParams.DeviceNumber;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,67 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.Code.AppExtend
|
||||
{
|
||||
/// <summary>
|
||||
/// 阿里云配置
|
||||
/// </summary>
|
||||
public class AliyunConfig
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string AccessKeyId { get; set; }
|
||||
/// <summary>
|
||||
/// 配置环境变量
|
||||
/// </summary>
|
||||
public string AccessKeySecret { get; set; }
|
||||
|
||||
#region 阿里云OSS配置
|
||||
/// <summary>
|
||||
/// 替换为Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
|
||||
/// </summary>
|
||||
public string EndPoint { get; set; }
|
||||
/// <summary>
|
||||
/// Bucket名称。
|
||||
/// </summary>
|
||||
public string BucketName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上传路径
|
||||
/// </summary>
|
||||
public string UploadPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 域名
|
||||
/// </summary>
|
||||
public string? DomainName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 前缀
|
||||
/// </summary>
|
||||
public string ImagePrefix
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.DomainName; //+ this.UploadPath
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 短信签名名称
|
||||
/// </summary>
|
||||
public string SmsSignName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// string 短信模板配置
|
||||
/// </summary>
|
||||
public string SmsTemplateCode { get; set; }
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -1,117 +1,122 @@
|
|||
using CloudGaming.Code.AppExtend.Config;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.Code.AppExtend
|
||||
namespace CloudGaming.Code.AppExtend;
|
||||
|
||||
/// <summary>
|
||||
/// 项目配置
|
||||
/// </summary>
|
||||
public class AppConfig
|
||||
{
|
||||
public AppConfig() { }
|
||||
/// <summary>
|
||||
/// 项目配置
|
||||
/// 用户数据库连接字符串
|
||||
/// </summary>
|
||||
public class AppConfig
|
||||
public string UserConnectionString { get; set; }
|
||||
/// <summary>
|
||||
/// 游戏
|
||||
/// </summary>
|
||||
public string GameConnectionString { get; set; }
|
||||
/// <summary>
|
||||
/// 扩展
|
||||
/// </summary>
|
||||
public string ExtConnectionString { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 手机app配置
|
||||
/// </summary>
|
||||
public string PhoneConnectionString { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// redis连接字符串
|
||||
/// </summary>
|
||||
public string RedisConnectionString { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 域名
|
||||
/// </summary>
|
||||
public string DomainName { get; set; }
|
||||
/// <summary>
|
||||
/// 标识
|
||||
/// </summary>
|
||||
public string Identifier { get; set; }
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认语言
|
||||
/// </summary>
|
||||
public string DefaultLanguage { get; set; }
|
||||
/// <summary>
|
||||
/// 租户
|
||||
/// </summary>
|
||||
public Guid TenantId { get; set; }
|
||||
/// <summary>
|
||||
/// 项目支付数据
|
||||
/// </summary>
|
||||
//public PaymentModel? Payment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// oss阿里云配置
|
||||
/// </summary>
|
||||
public AliyunConfig AliyunConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户默认配置
|
||||
/// </summary>
|
||||
public UserConfig UserConfig { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据库连接字符串
|
||||
/// </summary>
|
||||
/// <param name="key">user,game,ext,phone</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public string GetConnectionString(AppDataBaseType appDataBaseType)
|
||||
{
|
||||
public AppConfig() { }
|
||||
/// <summary>
|
||||
/// 用户数据库连接字符串
|
||||
/// </summary>
|
||||
public string UserConnectionString { get; set; }
|
||||
/// <summary>
|
||||
/// 游戏
|
||||
/// </summary>
|
||||
public string GameConnectionString { get; set; }
|
||||
/// <summary>
|
||||
/// 扩展
|
||||
/// </summary>
|
||||
public string ExtConnectionString { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 手机app配置
|
||||
/// </summary>
|
||||
public string PhoneConnectionString { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// redis连接字符串
|
||||
/// </summary>
|
||||
public string RedisConnectionString { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 域名
|
||||
/// </summary>
|
||||
public string DomainName { get; set; }
|
||||
/// <summary>
|
||||
/// 标识
|
||||
/// </summary>
|
||||
public string Identifier { get; set; }
|
||||
/// <summary>
|
||||
/// 名称
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 默认语言
|
||||
/// </summary>
|
||||
public string DefaultLanguage { get; set; }
|
||||
/// <summary>
|
||||
/// 租户
|
||||
/// </summary>
|
||||
public Guid TenantId { get; set; }
|
||||
/// <summary>
|
||||
/// 项目支付数据
|
||||
/// </summary>
|
||||
//public PaymentModel? Payment { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// oss阿里云配置
|
||||
/// </summary>
|
||||
public AliyunConfig AliyunConfig { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取数据库连接字符串
|
||||
/// </summary>
|
||||
/// <param name="key">user,game,ext,phone</param>
|
||||
/// <returns></returns>
|
||||
/// <exception cref="NotImplementedException"></exception>
|
||||
public string GetConnectionString(AppDataBaseType appDataBaseType)
|
||||
switch (appDataBaseType)
|
||||
{
|
||||
switch (appDataBaseType)
|
||||
{
|
||||
case AppDataBaseType.User:
|
||||
return UserConnectionString;
|
||||
case AppDataBaseType.Game:
|
||||
return GameConnectionString;
|
||||
case AppDataBaseType.Ext:
|
||||
return ExtConnectionString;
|
||||
case AppDataBaseType.App:
|
||||
return PhoneConnectionString;
|
||||
default:
|
||||
throw new NotImplementedException("数据库连接字符串不存在");
|
||||
}
|
||||
case AppDataBaseType.User:
|
||||
return UserConnectionString;
|
||||
case AppDataBaseType.Game:
|
||||
return GameConnectionString;
|
||||
case AppDataBaseType.Ext:
|
||||
return ExtConnectionString;
|
||||
case AppDataBaseType.App:
|
||||
return PhoneConnectionString;
|
||||
default:
|
||||
throw new NotImplementedException("数据库连接字符串不存在");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据库选项
|
||||
/// </summary>
|
||||
|
||||
public enum AppDataBaseType
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户数据库
|
||||
/// </summary>
|
||||
User,
|
||||
/// <summary>
|
||||
/// 游戏数据库
|
||||
/// </summary>
|
||||
Game,
|
||||
/// <summary>
|
||||
/// 扩展数据库
|
||||
/// </summary>
|
||||
Ext,
|
||||
/// <summary>
|
||||
/// app数据库
|
||||
/// </summary>
|
||||
App
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数据库选项
|
||||
/// </summary>
|
||||
|
||||
public enum AppDataBaseType
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户数据库
|
||||
/// </summary>
|
||||
User,
|
||||
/// <summary>
|
||||
/// 游戏数据库
|
||||
/// </summary>
|
||||
Game,
|
||||
/// <summary>
|
||||
/// 扩展数据库
|
||||
/// </summary>
|
||||
Ext,
|
||||
/// <summary>
|
||||
/// app数据库
|
||||
/// </summary>
|
||||
App
|
||||
}
|
||||
|
|
|
|||
|
|
@ -176,6 +176,11 @@ namespace CloudGaming.Code.AppExtend
|
|||
newAppConfig.PhoneConnectionString = appConfig.PhoneConnectionString;
|
||||
newAppConfig.AliyunConfig = appConfig.AliyunConfig;
|
||||
newAppConfig.DefaultLanguage = appConfig.DefaultLanguage;
|
||||
if (appConfig.UserConfig == null)
|
||||
{
|
||||
appConfig.UserConfig = new UserConfig();
|
||||
}
|
||||
newAppConfig.UserConfig = appConfig.UserConfig;
|
||||
return newAppConfig;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,67 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.Code.AppExtend.Config;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 阿里云配置
|
||||
/// </summary>
|
||||
public class AliyunConfig
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public string AccessKeyId { get; set; }
|
||||
/// <summary>
|
||||
/// 配置环境变量
|
||||
/// </summary>
|
||||
public string AccessKeySecret { get; set; }
|
||||
|
||||
#region 阿里云OSS配置
|
||||
/// <summary>
|
||||
/// 替换为Bucket所在地域对应的Endpoint。以华东1(杭州)为例,Endpoint填写为https://oss-cn-hangzhou.aliyuncs.com。
|
||||
/// </summary>
|
||||
public string EndPoint { get; set; }
|
||||
/// <summary>
|
||||
/// Bucket名称。
|
||||
/// </summary>
|
||||
public string BucketName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 上传路径
|
||||
/// </summary>
|
||||
public string UploadPath { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 域名
|
||||
/// </summary>
|
||||
public string? DomainName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 前缀
|
||||
/// </summary>
|
||||
public string ImagePrefix
|
||||
{
|
||||
get
|
||||
{
|
||||
return this.DomainName; //+ this.UploadPath
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// 短信签名名称
|
||||
/// </summary>
|
||||
public string SmsSignName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// string 短信模板配置
|
||||
/// </summary>
|
||||
public string SmsTemplateCode { get; set; }
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.Code.AppExtend.Config;
|
||||
|
||||
/// <summary>
|
||||
/// 用户默认配置
|
||||
/// </summary>
|
||||
public class UserConfig
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户默认头像
|
||||
/// </summary>
|
||||
public string UserIconUrl { get; set; }
|
||||
/// <summary>
|
||||
/// 用户默认昵称
|
||||
/// </summary>
|
||||
public string NickName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户最大登录设备
|
||||
/// </summary>
|
||||
public int MaxDeviceCount { get; set; }
|
||||
}
|
||||
|
|
@ -8,6 +8,7 @@ using System.Text;
|
|||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace CloudGaming.Code.AppExtend
|
||||
{
|
||||
|
|
@ -65,6 +66,57 @@ namespace CloudGaming.Code.AppExtend
|
|||
//指定允许令牌的时钟偏移。允许令牌的过期时间与实际时间之间存在的时间差。在这里设置为 5 分钟,表示允许令牌的时钟偏移为 5 分钟。
|
||||
ClockSkew = TimeSpan.FromMinutes(5)
|
||||
};
|
||||
options.Events = new JwtBearerEvents
|
||||
{
|
||||
OnTokenValidated = async context =>
|
||||
{
|
||||
var userId = context.Principal.FindFirst("userId")?.Value;
|
||||
if (userId == null || true)
|
||||
{
|
||||
context.Fail("Token missing userId claim.");
|
||||
return;
|
||||
}
|
||||
|
||||
//// 你可以调用数据库或其他服务来验证用户状态
|
||||
//var userService = context.HttpContext.RequestServices.GetRequiredService<IUserService>();
|
||||
//var user = await userService.GetUserByIdAsync(userId);
|
||||
//if (user == null || !user.IsActive)
|
||||
//{
|
||||
// context.Fail("User is inactive or not found.");
|
||||
//}
|
||||
},
|
||||
// 处理认证失败的事件
|
||||
OnAuthenticationFailed = context =>
|
||||
{
|
||||
// 在这里可以根据需要设置自定义的HTTP状态码
|
||||
context.Response.StatusCode = StatusCodes.Status403Forbidden; // 设置为 403 Forbidden
|
||||
context.Response.ContentType = "application/json";
|
||||
|
||||
// 返回自定义的错误消息
|
||||
var result = JsonSerializer.Serialize(new { error = context.Exception?.Message });
|
||||
return context.Response.WriteAsync(result);
|
||||
},
|
||||
// 在认证失败并被 Challenge 时触发该事件
|
||||
OnChallenge = context =>
|
||||
{
|
||||
// 如果已经有错误消息,则根据错误原因返回自定义状态码
|
||||
if (context.AuthenticateFailure != null)
|
||||
{
|
||||
context.HandleResponse(); // 确保不再执行默认的挑战响应
|
||||
context.Response.Clear(); // 清空现有响应内容
|
||||
context.Response.StatusCode = StatusCodes.Status200OK; // 设置状态码为403 Forbidden
|
||||
context.Response.ContentType = "application/json";
|
||||
|
||||
// 构建自定义的 JSON 响应
|
||||
var result = JsonSerializer.Serialize(new { error = context.AuthenticateFailure.Message });
|
||||
return context.Response.WriteAsync(result); // 写入响应
|
||||
}
|
||||
|
||||
// 默认情况下返回 401 Unauthorized
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
};
|
||||
|
||||
});
|
||||
//注册一个JwtAuthManager的单例服务
|
||||
builder.Services.AddSingleton<IJwtAuthManager, JwtManager>();
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ namespace CloudGaming.Code.Config
|
|||
IsAuthRealName = true
|
||||
};
|
||||
appConfigDto.IsChecking = IsChecking;
|
||||
appConfigDto.SignKey = AppConfig.TenantId.ToString("N");
|
||||
return appConfigDto;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ namespace CloudGaming.Code.Filter
|
|||
{
|
||||
var sw = Stopwatch.StartNew();
|
||||
// 检查异常是否是特定的异常类型
|
||||
if (context.Exception is MessageException message)
|
||||
if (context.Exception is MessageBox message)
|
||||
{
|
||||
var obj = new BaseResponse<object>(message.Code, message.Message, message.Data);
|
||||
//// 处理特定异常:记录日志、设置响应结果等
|
||||
|
|
|
|||
|
|
@ -19,5 +19,5 @@ global using Microsoft.EntityFrameworkCore;
|
|||
global using Microsoft.Extensions.Configuration;
|
||||
global using Microsoft.Extensions.DependencyInjection;
|
||||
global using Microsoft.Extensions.Hosting;
|
||||
|
||||
global using CloudGaming.Code.AppExtend.Config;
|
||||
global using System.Diagnostics;
|
||||
|
|
@ -1,45 +1,46 @@
|
|||
using HuanMeng.DotNetCore.MiddlewareExtend;
|
||||
namespace CloudGaming.Code.MiddlewareExtend;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.Code.MiddlewareExtend
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public static class MiddlewareExtends
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// 加载全部中间件
|
||||
/// </summary>
|
||||
public static class MiddlewareExtends
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseCloudGamingMiddlewareAll(this IApplicationBuilder builder)
|
||||
{
|
||||
/// <summary>
|
||||
/// 加载全部中间件
|
||||
/// </summary>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseCloudGamingMiddlewareAll(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder
|
||||
.UseCacheMiddleware()
|
||||
.UseRedisCacheMiddleware()
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 缓存中间件
|
||||
/// </summary>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseCacheMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<MemoryCacheMiddleware>();
|
||||
}
|
||||
public static IApplicationBuilder UseRedisCacheMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<RedisCacheMiddleware>();
|
||||
}
|
||||
return builder
|
||||
.UseSignMiddleware()
|
||||
.UseCacheMiddleware()
|
||||
.UseRedisCacheMiddleware()
|
||||
;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 缓存中间件
|
||||
/// </summary>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseCacheMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<MemoryCacheMiddleware>();
|
||||
}
|
||||
public static IApplicationBuilder UseRedisCacheMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<RedisCacheMiddleware>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 加密验证
|
||||
/// </summary>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseSignMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<SignMiddleware>();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,98 @@
|
|||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.Code.MiddlewareExtend;
|
||||
|
||||
/// <summary>
|
||||
/// 参数请求加密验证
|
||||
/// </summary>
|
||||
public class SignMiddleware
|
||||
{
|
||||
|
||||
private readonly RequestDelegate _next;
|
||||
public SignMiddleware(RequestDelegate next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
||||
public async Task InvokeAsync(HttpContext context, AppConfig appConfig)
|
||||
{ // 读取请求体
|
||||
context.Request.EnableBuffering();
|
||||
if (context.Request.Method != "POST" || context.Request.Host.Host == "localhost")
|
||||
{
|
||||
// 调用下一个中间件
|
||||
await _next(context);
|
||||
return;
|
||||
}
|
||||
|
||||
// 启用请求流的多次读取功能
|
||||
var requestBody = await new StreamReader(context.Request.Body).ReadToEndAsync();
|
||||
context.Request.Body.Position = 0; // 重置请求体的位置
|
||||
|
||||
if (string.IsNullOrEmpty(requestBody))
|
||||
{
|
||||
await _next(context);
|
||||
return;
|
||||
}
|
||||
// 解析请求体为 JSON 对象
|
||||
var requestJson = JObject.Parse(requestBody);
|
||||
// 获取请求中的 sign 值
|
||||
var requestSign = requestJson["sign"]?.ToString();
|
||||
if (string.IsNullOrEmpty(requestSign))
|
||||
{
|
||||
var response = GetSignError(context);
|
||||
context.Response.ContentType = "application/json; charset=utf-8";
|
||||
await context.Response.WriteAsync(response);
|
||||
return;
|
||||
}
|
||||
// 获取所有的键值对,并排序
|
||||
var sortedKeys = requestJson.Properties()
|
||||
.Where(p => p.Name != "sign")
|
||||
.OrderBy(p => p.Name)
|
||||
.Select(p => p.Value.ToString())
|
||||
.ToList();
|
||||
|
||||
// 拼接所有的值,并加上固定字符串
|
||||
var concatenatedValues = string.Join("", sortedKeys) + appConfig.TenantId.ToString("N");
|
||||
|
||||
// 计算 MD5 哈希值
|
||||
var md5Hash = MD5Encryption.ComputeMD5Hash(concatenatedValues);
|
||||
// 验证 MD5 哈希值与请求中的 sign 是否匹配
|
||||
if (md5Hash != requestSign)
|
||||
{
|
||||
var response = GetSignError(context);
|
||||
context.Response.ContentType = "application/json; charset=utf-8";
|
||||
context.Response.Headers["X-Request-Sign-Value"] = concatenatedValues;
|
||||
context.Response.Headers["X-Request-Sign"] = md5Hash;
|
||||
// 将异常信息写入 HTTP 响应
|
||||
await context.Response.WriteAsync(response);
|
||||
//await context.Response.WriteAsync("");
|
||||
return;
|
||||
}
|
||||
|
||||
// 调用下一个中间件
|
||||
await _next(context);
|
||||
}
|
||||
|
||||
private static string GetSignError(HttpContext context)
|
||||
{
|
||||
var settings = new JsonSerializerSettings
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver()
|
||||
};
|
||||
// 返回 500 错误
|
||||
context.Response.StatusCode = 200;
|
||||
BaseResponse<object> baseResponse = new BaseResponse<object>(ResonseCode.SignError, "sign加密验证失败", null)
|
||||
{ };
|
||||
var json = JsonConvert.SerializeObject(baseResponse, settings);
|
||||
return json;
|
||||
}
|
||||
}
|
||||
|
|
@ -36,7 +36,7 @@ namespace CloudGaming.Code.Sms
|
|||
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
|
||||
AccessKeyId = "LTAI5tEMoHbcDC5d9CQWovJk",//aliyunOssConfig.AccessKeyId, //Environment.GetEnvironmentVariable("ALIBABA_CLOUD_ACCESS_KEY_ID"),
|
||||
// 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
|
||||
AccessKeySecret = "gnYOJr0l9hTnl82vI4BxwVgtE1RdL"// aliyunOssConfig.AccessKeySecret,
|
||||
AccessKeySecret = "DgnYOJr0l9hTnl82vI4BxwVgtE1RdL"// aliyunOssConfig.AccessKeySecret,
|
||||
};
|
||||
// Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
|
||||
config.Endpoint = "dysmsapi.aliyuncs.com";
|
||||
|
|
@ -58,12 +58,15 @@ namespace CloudGaming.Code.Sms
|
|||
SignName = aliyunOssConfig.SmsSignName,// "氢荷健康",
|
||||
TemplateCode = aliyunOssConfig.SmsTemplateCode,// "SMS_154950909",
|
||||
PhoneNumbers = phoneNumber,
|
||||
TemplateParam = "{\"code\":\"" + code + "\"}",
|
||||
TemplateParam = "{\"code\":\"" + code + "\"}"// "{\"code\":\"" + code + "\"}",
|
||||
};
|
||||
AlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
|
||||
try
|
||||
{
|
||||
// 复制代码运行请自行打印 API 的返回值
|
||||
var response = await client.SendSmsWithOptionsAsync(sendSmsRequest, new AlibabaCloud.TeaUtil.Models.RuntimeOptions());
|
||||
// 复制代码运行请自行打印 API 的返回值
|
||||
//client.SendSmsWithOptions(sendSmsRequest, runtime);
|
||||
var response = await client.SendSmsWithOptionsAsync(sendSmsRequest, runtime);
|
||||
}
|
||||
catch (TeaException error)
|
||||
{
|
||||
|
|
@ -72,7 +75,7 @@ namespace CloudGaming.Code.Sms
|
|||
Console.WriteLine(error.Message);
|
||||
// 诊断地址
|
||||
Console.WriteLine(error.Data["Recommend"]);
|
||||
AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);
|
||||
var x = AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);
|
||||
throw error;
|
||||
}
|
||||
catch (Exception _error)
|
||||
|
|
@ -86,7 +89,7 @@ namespace CloudGaming.Code.Sms
|
|||
Console.WriteLine(error.Message);
|
||||
// 诊断地址
|
||||
Console.WriteLine(error.Data["Recommend"]);
|
||||
AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);
|
||||
var x = AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);
|
||||
throw error;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\Model\CloudGaming.DtoModel\CloudGaming.DtoModel.csproj" />
|
||||
<ProjectReference Include="..\..\Model\CloudGaming.Model\CloudGaming.Model.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
// See https://aka.ms/new-console-template for more information
|
||||
using CloudGaming.Model.DbSqlServer.Db_Phone;
|
||||
using CloudGaming.Model.DbSqlServer.Db_User;
|
||||
|
||||
using CloudGaming.DtoModel.Account.Login;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
using Newtonsoft.Json;
|
||||
//var jsopn = JsonConvert.SerializeObject(new PhoneLoginParams());
|
||||
//Server=192.168.1.17;Database=CloudGamingUser;User Id=sa;Password=Dbt@com@123;TrustServerCertificate=true;
|
||||
var optionsBuilder = new DbContextOptionsBuilder<CloudGamingPhoneContext>();
|
||||
var option = optionsBuilder.UseSqlServer("Server=192.168.1.17;Database=CloudGamingPhone;User Id=sa;Password=Dbt@com@123;TrustServerCertificate=true;").Options;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.DtoModel.Account
|
||||
{
|
||||
/// <summary>
|
||||
/// 登录返回的数据
|
||||
/// </summary>
|
||||
public class AccountLogInResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// token
|
||||
/// </summary>
|
||||
public string Token { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 昵称
|
||||
/// </summary>
|
||||
public string NickName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户id
|
||||
/// </summary>
|
||||
public int UserId { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.DtoModel.Account.Login
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class AccountUserLoginInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// 登录使用的tokens
|
||||
/// </summary>
|
||||
public string Token { get; set; }
|
||||
/// <summary>
|
||||
/// 过期时间
|
||||
/// </summary>
|
||||
public DateTime ExpirationDate { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.DtoModel.Account.Login
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class BaseLoginParams
|
||||
{
|
||||
/// <summary>
|
||||
/// 设备号
|
||||
/// </summary>
|
||||
public string? DeviceNumber { get; set; } = "";
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.DtoModel.Account.Login;
|
||||
|
||||
/// <summary>
|
||||
/// 验证码登录
|
||||
/// </summary>
|
||||
public class PhoneLoginParams : BaseLoginParams
|
||||
{
|
||||
/// <summary>
|
||||
/// 手机号码
|
||||
/// </summary>
|
||||
public string PhoneNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 验证码
|
||||
/// </summary>
|
||||
public string VerificationCode { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace CloudGaming.DtoModel.Account
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户数据属性
|
||||
/// </summary>
|
||||
public enum UserDataPropertyEnum
|
||||
{
|
||||
/// <summary>
|
||||
/// 手机号
|
||||
/// </summary>
|
||||
PhoneNum = 1,
|
||||
/// <summary>
|
||||
/// 邮箱
|
||||
/// </summary>
|
||||
Email = 2
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,10 @@ public class AppConfigDto
|
|||
//[Images]
|
||||
//public int OpenImage { get; set; }
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 加密key
|
||||
/// </summary>
|
||||
public string SignKey { get; set; }
|
||||
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -59,6 +59,11 @@ public partial class CloudGamingCBTContext : DbContext
|
|||
/// </summary>
|
||||
public virtual DbSet<T_Sms_Log> T_Sms_Log { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户登录日志表
|
||||
/// </summary>
|
||||
public virtual DbSet<T_User_Login_Log> T_User_Login_Log { 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;");
|
||||
|
||||
|
|
@ -150,14 +155,14 @@ public partial class CloudGamingCBTContext : DbContext
|
|||
|
||||
entity.ToTable(tb => tb.HasComment("发送短信日志表"));
|
||||
|
||||
entity.HasIndex(e => e.SendTimeDay, "T_Sms_Log_SendTimeDay_index_desc").IsDescending();
|
||||
entity.HasIndex(e => new { e.SendTimeDay, e.PhoneNumber }, "T_Sms_Log_SendTimeDay_index_desc").IsDescending(true, false);
|
||||
|
||||
entity.Property(e => e.Id).HasComment("主键");
|
||||
entity.Property(e => e.ErrorMessage)
|
||||
.HasMaxLength(255)
|
||||
.HasComment("错误信息(如果发送失败)");
|
||||
entity.Property(e => e.PhoneNumber)
|
||||
.HasMaxLength(1)
|
||||
.HasMaxLength(20)
|
||||
.HasComment("手机号码");
|
||||
entity.Property(e => e.SendStatus).HasComment("发送状态(0: 失败, 1: 成功)\r\n");
|
||||
entity.Property(e => e.SendTime)
|
||||
|
|
@ -165,11 +170,41 @@ public partial class CloudGamingCBTContext : DbContext
|
|||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.SendTimeDay).HasComment("发送时间,天");
|
||||
entity.Property(e => e.VerificationCode)
|
||||
.HasMaxLength(1)
|
||||
.HasMaxLength(20)
|
||||
.HasComment("发送的验证码");
|
||||
|
||||
});
|
||||
|
||||
modelBuilder.Entity<T_User_Login_Log>(entity =>
|
||||
{
|
||||
entity.HasKey(e => e.Id).HasName("PK__T_User_L__3214EC07C2A990A7");
|
||||
|
||||
entity.ToTable(tb => tb.HasComment("用户登录日志表"));
|
||||
|
||||
entity.Property(e => e.Id).HasComment("主键");
|
||||
entity.Property(e => e.AppVersion)
|
||||
.HasMaxLength(10)
|
||||
.HasComment("app版本");
|
||||
entity.Property(e => e.Channel)
|
||||
.HasMaxLength(20)
|
||||
.HasComment("渠道");
|
||||
entity.Property(e => e.CreateTime)
|
||||
.HasComment("创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.CreateTimeDay).HasComment("创建时间天");
|
||||
entity.Property(e => e.CreateTimeHour).HasComment("创建时间小时");
|
||||
entity.Property(e => e.Ip)
|
||||
.HasMaxLength(50)
|
||||
.HasComment("登录IP");
|
||||
entity.Property(e => e.IsNew).HasComment("是否新增用户");
|
||||
entity.Property(e => e.LoginType).HasComment("登录方式");
|
||||
entity.Property(e => e.PlatformType)
|
||||
.HasMaxLength(10)
|
||||
.HasComment("登录平台");
|
||||
entity.Property(e => e.UserId).HasComment("用户Id");
|
||||
|
||||
});
|
||||
|
||||
OnModelCreatingPartial(modelBuilder);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
|
||||
namespace CloudGaming.GameModel.Db.Db_Ext;
|
||||
|
||||
/// <summary>
|
||||
/// 用户登录日志表
|
||||
/// </summary>
|
||||
public partial class T_User_Login_Log
|
||||
{
|
||||
public T_User_Login_Log() { }
|
||||
|
||||
/// <summary>
|
||||
/// 主键
|
||||
/// </summary>
|
||||
public virtual int Id { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 用户Id
|
||||
/// </summary>
|
||||
public virtual int UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 登录IP
|
||||
/// </summary>
|
||||
public virtual string Ip { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 是否新增用户
|
||||
/// </summary>
|
||||
public virtual bool IsNew { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 登录方式
|
||||
/// </summary>
|
||||
public virtual int LoginType { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 登录平台
|
||||
/// </summary>
|
||||
public virtual string PlatformType { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// app版本
|
||||
/// </summary>
|
||||
public virtual string AppVersion { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间天
|
||||
/// </summary>
|
||||
public virtual int CreateTimeDay { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间小时
|
||||
/// </summary>
|
||||
public virtual int CreateTimeHour { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public virtual DateTime CreateTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 渠道
|
||||
/// </summary>
|
||||
public virtual string Channel { get; set; } = null!;
|
||||
}
|
||||
|
|
@ -413,9 +413,6 @@ public partial class CloudGamingUserContext : MultiTenantDbContext//DbContext
|
|||
.HasComment("修改时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.IsLogout).HasComment("是否注销");
|
||||
entity.Property(e => e.LastLoginAt)
|
||||
.HasComment("最后一次登录时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.NikeName)
|
||||
.HasMaxLength(100)
|
||||
.HasComment("用户昵称")
|
||||
|
|
@ -430,11 +427,6 @@ public partial class CloudGamingUserContext : MultiTenantDbContext//DbContext
|
|||
.HasComment("创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.UserId).HasComment("用户Id");
|
||||
entity.Property(e => e.VerificationCode)
|
||||
.HasMaxLength(10)
|
||||
.IsUnicode(false)
|
||||
.HasComment("验证码")
|
||||
.UseCollation("Chinese_PRC_CI_AS");
|
||||
//添加全局筛选器
|
||||
if (this.TenantInfo != null)
|
||||
{
|
||||
|
|
@ -451,11 +443,20 @@ public partial class CloudGamingUserContext : MultiTenantDbContext//DbContext
|
|||
entity.Property(e => e.CreateAt)
|
||||
.HasComment("创建时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.DeviceNumber)
|
||||
.HasMaxLength(100)
|
||||
.HasComment("设备号");
|
||||
entity.Property(e => e.ExpiresAt)
|
||||
.HasComment("过期时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.LastLoginAt)
|
||||
.HasComment("最后一次登录时间")
|
||||
.HasColumnType("datetime");
|
||||
entity.Property(e => e.TenantId).HasComment("租户");
|
||||
entity.Property(e => e.Token).HasComment("登录token");
|
||||
entity.Property(e => e.TokenMd5)
|
||||
.HasMaxLength(64)
|
||||
.HasComment("tokenMd5值");
|
||||
entity.Property(e => e.UpdateAt)
|
||||
.HasComment("修改时间")
|
||||
.HasColumnType("datetime");
|
||||
|
|
|
|||
|
|
@ -29,16 +29,6 @@ public partial class T_User_Phone_Account: MultiTenantEntity
|
|||
/// </summary>
|
||||
public virtual string PhoneNum { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 验证码
|
||||
/// </summary>
|
||||
public virtual string VerificationCode { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 最后一次登录时间
|
||||
/// </summary>
|
||||
public virtual DateTime LastLoginAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 修改时间
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -40,4 +40,19 @@ public partial class T_User_Token: MultiTenantEntity
|
|||
/// 修改时间
|
||||
/// </summary>
|
||||
public virtual DateTime? UpdateAt { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 设备号
|
||||
/// </summary>
|
||||
public virtual string? DeviceNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// tokenMd5值
|
||||
/// </summary>
|
||||
public virtual string? TokenMd5 { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 最后一次登录时间
|
||||
/// </summary>
|
||||
public virtual DateTime LastLoginAt { get; set; }
|
||||
}
|
||||
|
|
|
|||
115
src/CloudGaming/Utile/HuanMeng.DotNetCore/Base/MessageBox.cs
Normal file
115
src/CloudGaming/Utile/HuanMeng.DotNetCore/Base/MessageBox.cs
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
using Microsoft.AspNetCore.SignalR.Protocol;
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.DotNetCore.Base
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MessageBox : Exception
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
public MessageBox(ResonseCode code)
|
||||
{
|
||||
Code = (int)code;
|
||||
Message = "";
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
public MessageBox(ResonseCode code, string message, object? data = null)
|
||||
{
|
||||
Code = (int)code;
|
||||
Message = message;
|
||||
Data = data;
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
public MessageBox(int code, string message, object? data = null)
|
||||
{
|
||||
Code = code;
|
||||
Message = message;
|
||||
Data = data;
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
public MessageBox(string message, object? data = null)
|
||||
{
|
||||
Code = 0;
|
||||
Message = message;
|
||||
Data = data;
|
||||
}
|
||||
/// <summary>
|
||||
/// 功能执行返回代码
|
||||
/// </summary>
|
||||
public int Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据
|
||||
/// </summary>
|
||||
public object? Data { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建错误消息
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public static MessageBox ErrorShow(string message) => new(ResonseCode.Error, message);
|
||||
|
||||
/// <summary>
|
||||
/// 创建消息
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <returns></returns>
|
||||
public static MessageBox Show(string message) => new(message);
|
||||
|
||||
/// <summary>
|
||||
/// 创建消息 输出消息和数据
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
public static MessageBox Show(string message, object data) => new(message, data);
|
||||
|
||||
/// <summary>
|
||||
/// 创建消息 输出消息和数据
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public static MessageBox Show(int code, string message, object? data = null) => new(code, message, data);
|
||||
|
||||
/// <summary>
|
||||
/// 创建消息 输出消息和数据
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public static MessageBox Show(ResonseCode code, string message, object? data = null) => new(code, message, data);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,74 +0,0 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace HuanMeng.DotNetCore.Base
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
public class MessageException : Exception
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
public MessageException(ResonseCode code)
|
||||
{
|
||||
Code = (int)code;
|
||||
Message = "";
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
public MessageException(ResonseCode code, string message, object? data = null)
|
||||
{
|
||||
Code = (int)code;
|
||||
Message = message;
|
||||
Data = data;
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="code"></param>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
public MessageException(int code, string message, object? data = null)
|
||||
{
|
||||
Code = code;
|
||||
Message = message;
|
||||
Data = data;
|
||||
}
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="message"></param>
|
||||
/// <param name="data"></param>
|
||||
public MessageException(string message, object? data = null)
|
||||
{
|
||||
Code = 0;
|
||||
Message = message;
|
||||
Data = data;
|
||||
}
|
||||
/// <summary>
|
||||
/// 功能执行返回代码
|
||||
/// </summary>
|
||||
public int Code { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 消息
|
||||
/// </summary>
|
||||
public string Message { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 数据
|
||||
/// </summary>
|
||||
public object? Data { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
@ -54,6 +54,11 @@ public enum ResonseCode
|
|||
/// </summary>
|
||||
NotFoundRecord = -3,
|
||||
|
||||
/// <summary>
|
||||
/// 数据为null
|
||||
/// </summary>
|
||||
NullOrEmpty = -4,
|
||||
|
||||
/// <summary>
|
||||
/// 成功
|
||||
/// </summary>
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace HuanMeng.DotNetCore.MiddlewareExtend
|
|||
return builder
|
||||
.UseExceptionMiddleware()
|
||||
.UseExecutionTimeMiddleware()
|
||||
.UseSignMiddleware()
|
||||
//.SignBaseMiddleware()
|
||||
;
|
||||
|
||||
}
|
||||
|
|
@ -46,9 +46,9 @@ namespace HuanMeng.DotNetCore.MiddlewareExtend
|
|||
/// </summary>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseSignMiddleware(this IApplicationBuilder builder)
|
||||
public static IApplicationBuilder SignBaseMiddleware(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<SignMiddleware>();
|
||||
return builder.UseMiddleware<SignBaseMiddleware>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,11 +15,11 @@ namespace HuanMeng.DotNetCore.MiddlewareExtend
|
|||
/// <summary>
|
||||
/// 参数请求加密验证
|
||||
/// </summary>
|
||||
public class SignMiddleware
|
||||
public class SignBaseMiddleware
|
||||
{
|
||||
private readonly RequestDelegate _next;
|
||||
private const string FixedString = "cccc"; // 固定字符串
|
||||
public SignMiddleware(RequestDelegate next)
|
||||
public SignBaseMiddleware(RequestDelegate next)
|
||||
{
|
||||
_next = next;
|
||||
}
|
||||
|
|
@ -84,6 +84,33 @@ namespace HuanMeng.DotNetCore.Redis
|
|||
// 将 RedisValue 转换为 T 类型
|
||||
return JsonConvert.DeserializeObject<T>(value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取一个key的对象
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static async Task<T?> StringGetAsync<T>(this IDatabase database, string key)
|
||||
{
|
||||
var value = await database.StringGetAsync(key);
|
||||
// 检查值是否为空
|
||||
if (!value.HasValue)
|
||||
{
|
||||
return default(T);
|
||||
}
|
||||
if (typeof(T).IsPrimitive || typeof(T) == typeof(string) || typeof(T) == typeof(decimal))
|
||||
{
|
||||
try
|
||||
{
|
||||
return (T)Convert.ChangeType(value.ToString(), typeof(T));
|
||||
}
|
||||
catch
|
||||
{
|
||||
return default; // 或抛出异常,取决于业务需求
|
||||
}
|
||||
}
|
||||
// 将 RedisValue 转换为 T 类型
|
||||
return JsonConvert.DeserializeObject<T>(value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ public class PhoneNumberValidator
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return phoneNumberRegex.IsMatch(input);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user