diff --git a/README.md b/README.md
index d653fc5..254597d 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,13 @@
# CloudGaming
-云游戏
\ No newline at end of file
+云游戏
+
+# CloudGaming
+
+云游戏
+
+## 发布
+cd /disk/CodeManage/CloudGaming/src/CloudGaming
+docker build -t cloudgaming:dev-0.0.4 -f Api/CloudGaming.Api/Dockerfile .
+
+docker run -d -p 81:80 cloudgaming:dev-0.0.4
\ No newline at end of file
diff --git a/src/CloudGaming/Api/CloudGaming.Api/Controllers/AccountController.cs b/src/CloudGaming/Api/CloudGaming.Api/Controllers/AccountController.cs
index f151cfa..e7d5621 100644
--- a/src/CloudGaming/Api/CloudGaming.Api/Controllers/AccountController.cs
+++ b/src/CloudGaming/Api/CloudGaming.Api/Controllers/AccountController.cs
@@ -68,4 +68,16 @@ public class AccountController : CloudGamingControllerBase
AccountBLL account = new AccountBLL(ServiceProvider);
return await account.GetUserInfo();
}
+
+ ///
+ /// 获取用户信息
+ ///
+ ///
+ [HttpPost]
+ [Authorize]
+ public async Task> RealAuthentication([FromBody] UserRealAuthenticationRequest authenticationRequest)
+ {
+ AccountBLL account = new AccountBLL(ServiceProvider);
+ return await account.RealAuthentication(authenticationRequest.UserName, authenticationRequest.IdCard, authenticationRequest.DeviceNumber);
+ }
}
diff --git a/src/CloudGaming/Code/CloudGaming.Code/Account/AccountBLL.cs b/src/CloudGaming/Code/CloudGaming.Code/Account/AccountBLL.cs
index 39fd2b1..1724ace 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/Account/AccountBLL.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/Account/AccountBLL.cs
@@ -1,6 +1,7 @@
using Alipay.EasySDK.Kernel;
using CloudGaming.Code.Account.Contract;
+using CloudGaming.Code.Contract;
using CloudGaming.Code.Sms;
using CloudGaming.DtoModel.Account;
using CloudGaming.DtoModel.Account.Login;
@@ -15,6 +16,8 @@ using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
+using Org.BouncyCastle.Utilities.Encoders;
+
using System;
using System.Collections.Generic;
using System.Linq;
@@ -130,9 +133,9 @@ namespace CloudGaming.Code.Account
userCurrency = new List();
}
var userCurrencyDic = userCurrency.ToDictionary(it => (UserCurrencyType)it.CurrencyType);
- var userInfoKey = GetUserInfoRedisKey(user.Id);
- var userInfo = LoadUserInfo(user, userData, userCurrencyDic);
- await RedisCache.StringSetAsync(userInfoKey, userInfo, TimeSpan.FromHours(1));
+ //创建用户缓存
+ await AccountExtend.LogUserInfoCahceAsync(RedisCache, user, userData, userCurrencyDic);
+
//创建jwt登录
var jwt = GenerateJwtToken(user);
var accountLogIn = new AccountLogInResponse
@@ -251,7 +254,8 @@ namespace CloudGaming.Code.Account
UpdateAt = DateTime.Now,
PhoneNum = account.GetUserDataProperty(UserDataPropertyEnum.PhoneNum),
UserId = userId,
- Email = account.GetUserDataProperty(UserDataPropertyEnum.Email)
+ Email = account.GetUserDataProperty(UserDataPropertyEnum.Email),
+ DeviceNumber = account.DeviceNumber
};
await Dao.DaoUser.Context.T_User_Data.AddAsync(userData);
await Dao.DaoUser.Context.SaveChangesAsync();
@@ -362,12 +366,8 @@ namespace CloudGaming.Code.Account
#endregion
- public string GetUserInfoRedisKey(int userId)
- {
- return $"user:userInfo:{userId}";
- }
///
- ///
+ /// 获取用户信息
///
///
public async Task GetUserInfo()
@@ -377,81 +377,230 @@ namespace CloudGaming.Code.Account
{
throw MessageBox.Show(ResonseCode.NotFoundRecord, "未找到用户");
}
- string key = GetUserInfoRedisKey(userId);
- var userInfo = await RedisCache.StringGetAsync(key);
- if (userInfo == null)
- {
- userInfo = new UserInfo() { };
- //用户信息
- var user = await Dao.DaoUser.Context.T_User.FirstOrDefaultAsync(it => it.Id == userId);
- //用户扩展信息
- var userData = await Dao.DaoUser.Context.T_User_Data.FirstOrDefaultAsync(it => it.UserId == userId);
- //用户货币
- var userCurrency = await Dao.DaoUser.Context.T_User_Currency.Where(it => it.UserId == userId).ToDictionaryAsync(it => (UserCurrencyType)it.CurrencyType);
- if (user == null)
- {
- throw MessageBox.Show(ResonseCode.NotFoundRecord, "未找到用户信息");
- }
- if (userData == null)
- {
- throw MessageBox.Show(ResonseCode.NotFoundRecord, "未找到用户扩展信息");
- }
-
- userInfo = LoadUserInfo(user, userData, userCurrency);
- await RedisCache.StringSetAsync(key, userInfo, TimeSpan.FromHours(1));
- }
+ UserInfoCache? userInfo = await GetUserInfoCache();
UserInfoDto userInfoDto = Mapper.Map(userInfo);
+ if (!string.IsNullOrEmpty(userInfoDto.UserName))
+ {
+ userInfoDto.UserName = userInfoDto.UserName.Length <= 2
+ ? userInfoDto.UserName.Substring(0, 1) + "*"
+ : userInfoDto.UserName.Substring(0, 1) + "*" + userInfoDto.UserName.Substring(userInfoDto.UserName.Length - 1);
+ }
+ // 将用户身份证号设置成 "前四位*后四位"
+ if (!string.IsNullOrEmpty(userInfoDto.IdCard) && userInfoDto.IdCard.Length >= 8)
+ {
+ userInfo.IdCard = userInfoDto.IdCard.Substring(0, 4) + "*********" + userInfoDto.IdCard.Substring(userInfoDto.IdCard.Length - 4);
+ }
return userInfoDto;
}
- ///
- /// 加载用户缓存
- ///
- ///
- ///
- ///
- ///
- ///
- private UserInfo LoadUserInfo(T_User? user, T_User_Data? userData, Dictionary userCurrency)
- {
- var userInfo = new UserInfo() { };
- userInfo.NickName = user.NickName;
- userInfo.UserId = user.Id;
- userInfo.UserIcon = user.UserIconUrl;
- userInfo.IsRealName = user.UserRealNameStatus > 0;
- userInfo.IsJuveniles = false;
- userInfo.UserName = "";
- userInfo.IdCard = "";
- if (userInfo.IsRealName)
- {
- userInfo.IsJuveniles = user.UserRealNameStatus == 2;
- if (!string.IsNullOrEmpty(user.UserName))
- {
- // 将用户昵称设置成 "陈*风" 或 "陈*"(如果只有两个字符)
- userInfo.UserName = user.UserName.Length <= 2
- ? user.UserName.Substring(0, 1) + "*"
- : user.UserName.Substring(0, 1) + "*" + user.UserName.Substring(user.UserName.Length - 1);
- }
- // 将用户身份证号设置成 "前四位*后四位"
- if (!string.IsNullOrEmpty(user.IDCard) && user.IDCard.Length >= 8)
- {
- userInfo.IdCard = user.IDCard.Substring(0, 4) + "*********" + user.IDCard.Substring(user.IDCard.Length - 4);
- }
- }
- userInfo.TotalGamingTime = 0;
- userInfo.PhoneNum = userData?.PhoneNum ?? "";
- userInfo.Email = userData?.Email ?? "";
- userInfo.Diamond = (int)userCurrency.GetUserCurrency(UserCurrencyType.钻石);
- return userInfo;
- }
-
+ #region 实名认证
///
/// 实名认证
///
///
- public async Task RealAuthentication(string userName, string idCard)
+ public async Task> RealAuthentication(string userName, string idCard, string deviceNumber)
{
- return true;
+ // 参数校验
+ ValidateParameters(userName, idCard);
+
+ // 检查用户信息和状态
+ CheckUserRealNameStatus(userName, idCard);
+
+ // 获取用户
+ var user = await Dao.DaoUser.Context.T_User.FirstOrDefaultAsync(it => it.Id == _UserId);
+ if (user == null)
+ {
+ throw CreateException(ResonseCode.NotFoundRecord, "用户不存在");
+ }
+
+ // 实名认证接口验证
+ var idCardVerify = this.GetIdCardVerify();
+ var (isv, msg) = await idCardVerify.IdCardVerify(userName, idCard);
+ if (!isv)
+ {
+ await LogRealAuthenticationFailure(userName, idCard, deviceNumber, msg);
+ throw CreateException(ResonseCode.NotFoundRecord, "身份证号错误");
+ }
+
+ // 更新用户实名认证状态
+ UpdateUserRealNameStatus(user, userName, idCard);
+
+ // 发放实名认证奖励
+ var rewardMessage = await GrantRewardsIfEligible(deviceNumber);
+
+ // 保存日志
+ await LogRealAuthenticationSuccess(userName, idCard, deviceNumber, rewardMessage);
+
+ // 更新缓存
+ await UpdateUserCache(userName, idCard);
+
+ return new BaseResponse(0, $"认证成功!{rewardMessage}") { }; ;
}
+
+ ///
+ /// 校验参数
+ ///
+ private void ValidateParameters(string userName, string idCard)
+ {
+ if (string.IsNullOrEmpty(userName))
+ {
+ throw CreateException(ResonseCode.ParamError, "用户名为空");
+ }
+ if (string.IsNullOrEmpty(idCard) || !OtherExtensions.ValidateIDCard(idCard))
+ {
+ throw CreateException(ResonseCode.ParamError, "身份证号错误");
+ }
+
+ }
+
+ ///
+ /// 检查用户实名认证状态
+ ///
+ private void CheckUserRealNameStatus(string userName, string idCard)
+ {
+ //判断用户是否实名认证过,并且不等于未成年人
+ if (UserInfo.IsRealName && !UserInfo.IsJuveniles)
+ {
+ throw MessageBox.Show(0, "此账号已实名认证成功,无需重复实名");
+ }
+ if (UserInfo.RealNameDateTimeLast != null && DateTime.Now.Subtract((UserInfo.RealNameDateTimeLast ?? DateTime.MinValue)).TotalSeconds < 10)
+ {
+ throw MessageBox.Show(ResonseCode.Error, "两次绑定身份证号时间间隔太短,请稍后再绑定~");
+ }
+ if (UserInfo.IdCard == idCard && UserInfo.UserName == userName)
+ {
+ throw MessageBox.Show(0, "此账号已实名认证成功,无需重复验证");
+ }
+ if (UserInfo.RealAuthentCount > 10)
+ {
+ throw MessageBox.Show(0, "此账号今日实名认证次数已到达上限");
+ }
+ }
+
+ ///
+ /// 更新用户实名认证状态
+ ///
+ private void UpdateUserRealNameStatus(T_User user, string userName, string idCard)
+ {
+ var (isValid, age, _, _) = OtherExtensions.GetIDCardBirthdayAgeSex(idCard);
+ user.UserName = userName;
+ user.IDCard = idCard;
+
+ if (isValid)
+ {
+ UserInfo.IsJuveniles = age < 18;
+ user.UserRealNameStatus = UserInfo.IsJuveniles ? 2 : 1;
+ }
+
+ UserInfo.IsRealName = true;
+ UserInfo.RealNameDateTimeLast = DateTime.Now;
+ UserInfo.RealAuthentCount++;
+ }
+
+ ///
+ /// 发放实名认证奖励
+ ///
+ private async Task GrantRewardsIfEligible(string deviceNumber)
+ {
+ if (string.IsNullOrEmpty(deviceNumber))
+ {
+ deviceNumber = UserInfo.DeviceNumber;
+ }
+
+ var hasUserReward = await Dao.DaoUser.Context.T_User_LimitActionLog
+ .AnyAsync(it => it.UserId == _UserId && it.ActionType == (int)UserActionTypeEnum.ActionType.实名认证);
+
+ if (hasUserReward)
+ {
+ return "用户已经领取过奖励,不再发放奖励";
+ }
+
+ var hasDeviceReward = await Dao.DaoUser.Context.T_User_LimitActionLog
+ .AnyAsync(it => it.DeviceNumber == deviceNumber && it.ActionType == (int)UserActionTypeEnum.ActionType.实名认证);
+
+ if (!hasDeviceReward)
+ {
+ var limitActionLog = new T_User_LimitActionLog
+ {
+ CreateTime = DateTime.Now,
+ CreateTimeDay = int.Parse(DateTime.Now.ToString("yyyyMMdd")),
+ ActionType = (int)UserActionTypeEnum.ActionType.实名认证,
+ DeviceNumber = deviceNumber,
+ UserId = _UserId,
+ Ip = HttpContextAccessor.HttpContext.GetClientIpAddress()
+ };
+
+ await Dao.DaoUser.Context.T_User_LimitActionLog.AddAsync(limitActionLog);
+ await Dao.DaoUser.Context.SaveChangesAsync();
+ return "奖励已经发送,钻石*10";
+ }
+
+ return "用户设备号重复,不发放奖励";
+ }
+
+ ///
+ /// 记录实名认证失败日志
+ ///
+ private async Task LogRealAuthenticationFailure(string userName, string idCard, string deviceNumber, string msg)
+ {
+ if (msg.Length > 100)
+ {
+ msg = msg.Substring(0, 100);
+ }
+ var log = new T_User_RealAuthentication_Log
+ {
+ CreateTime = DateTime.Now,
+ DeviceNumber = deviceNumber,
+ IdCard = idCard,
+ UserId = _UserId,
+ UserName = userName,
+ IsRewards = false,
+ RealResults = msg,
+ Message = "认证失败"
+ };
+
+ await Dao.DaoExt.Context.T_User_RealAuthentication_Log.AddAsync(log);
+ await Dao.DaoExt.Context.SaveChangesAsync();
+ UserInfo.RealNameDateTimeLast = DateTime.Now;
+ UserInfo.RealAuthentCount++;
+ await this.SaveUserInfoCacheChangesAsync();
+ }
+
+ ///
+ /// 记录实名认证成功日志
+ ///
+ private async Task LogRealAuthenticationSuccess(string userName, string idCard, string deviceNumber, string message)
+ {
+ var log = new T_User_RealAuthentication_Log
+ {
+ CreateTime = DateTime.Now,
+ DeviceNumber = deviceNumber,
+ IdCard = idCard,
+ UserId = _UserId,
+ UserName = userName,
+ IsRewards = message.Contains("奖励已经发送"),
+ RealResults = "认证成功",
+ Message = message
+ };
+
+ await Dao.DaoExt.Context.T_User_RealAuthentication_Log.AddAsync(log);
+ await Dao.DaoExt.Context.SaveChangesAsync();
+ }
+
+ ///
+ /// 更新用户缓存
+ ///
+ private async Task UpdateUserCache(string userName, string idCard)
+ {
+ UserInfo.UserName = userName;
+ UserInfo.IdCard = idCard;
+ UserInfo.IsRealName = true;
+ UserInfo.RealNameDateTimeLast = DateTime.Now;
+ UserInfo.RealAuthentCount++;
+ await this.SaveUserInfoCacheChangesAsync();
+ }
+
+ #endregion
+
}
}
diff --git a/src/CloudGaming/Code/CloudGaming.Code/Account/AccountExtend.cs b/src/CloudGaming/Code/CloudGaming.Code/Account/AccountExtend.cs
index 8eb425b..3745fa1 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/Account/AccountExtend.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/Account/AccountExtend.cs
@@ -1,11 +1,18 @@
using CloudGaming.Code.Account.Contract;
using CloudGaming.Code.Account.Login;
+using CloudGaming.Code.DataAccess;
using CloudGaming.DtoModel.Account.Login;
using CloudGaming.DtoModel.Account.User;
+using HuanMeng.DotNetCore.Redis;
+
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
+using StackExchange.Redis;
+
+using Swashbuckle.AspNetCore.SwaggerGen;
+
using System;
using System.Collections.Generic;
using System.Linq;
@@ -66,5 +73,151 @@ namespace CloudGaming.Code.Account
}
return 0;
}
+
+ ///
+ /// 用户缓存的key
+ ///
+ ///
+ ///
+ public static string GetUserInfoRedisKey(int userId)
+ {
+ return $"user:userInfo:{userId}";
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static async Task GetUserInfo(this UserInfoCache userInfoCache, int userId, CloudGamingBase cloudGamingBase)
+ {
+ userInfoCache = await GetUserInfo(userId, cloudGamingBase) ?? new UserInfoCache();
+ return userInfoCache;
+ }
+ ///
+ /// 获取用户信息
+ ///
+ ///
+ ///
+ ///
+ public static async Task GetUserInfo(int userId, CloudGamingBase cloudGamingBase)
+ {
+ if (userId == 0)
+ {
+ return new UserInfoCache();
+ }
+ string key = GetUserInfoRedisKey(userId);
+ var userInfo = await cloudGamingBase.RedisCache.StringGetAsync(key);
+ if (userInfo == null)
+ {
+ var Dao = cloudGamingBase.Dao;
+ userInfo = new UserInfoCache() { };
+ //用户信息
+ var user = await Dao.DaoUser.Context.T_User.FirstOrDefaultAsync(it => it.Id == userId);
+ //用户扩展信息
+ var userData = await Dao.DaoUser.Context.T_User_Data.FirstOrDefaultAsync(it => it.UserId == userId);
+ //用户货币
+ var userCurrency = await Dao.DaoUser.Context.T_User_Currency.Where(it => it.UserId == userId).ToDictionaryAsync(it => (UserCurrencyType)it.CurrencyType);
+ if (user == null)
+ {
+ throw MessageBox.Show(ResonseCode.NotFoundRecord, "未找到用户信息");
+ }
+ if (userData == null)
+ {
+ throw MessageBox.Show(ResonseCode.NotFoundRecord, "未找到用户扩展信息");
+ }
+
+ userInfo.LoadUserInfo(user, userData, userCurrency);
+ await cloudGamingBase.RedisCache.StringSetAsync(key, userInfo, TimeSpan.FromHours(1));
+ }
+
+ return userInfo;
+ }
+
+ ///
+ /// 设置用户信息
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static async Task LogUserInfoCahceAsync(IDatabase database, T_User user, T_User_Data? userData = null, Dictionary userCurrency = null)
+ {
+ var key = GetUserInfoRedisKey(user.Id);
+ var userInfo = new UserInfoCache() { };
+ LoadUserInfo(userInfo, user, userData, userCurrency);
+ await database.StringSetAsync(key, userInfo, TimeSpan.FromHours(1));
+ return userInfo;
+ }
+
+ ///
+ /// 加载用户缓存
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static UserInfoCache LoadUserInfo(this UserInfoCache userInfo, T_User? user = null, T_User_Data? userData = null, Dictionary userCurrency = null)
+ {
+ if (userInfo == null)
+ {
+ userInfo = new UserInfoCache();
+ }
+ if (user != null)
+ {
+ userInfo.NickName = user.NickName;
+ userInfo.UserId = user.Id;
+ userInfo.UserIcon = user.UserIconUrl;
+ userInfo.IsRealName = user.UserRealNameStatus > 0;
+ userInfo.IsJuveniles = user.UserRealNameStatus == 2;
+ userInfo.UserName = user.UserName ?? "";
+ userInfo.IdCard = user.IDCard ?? "";
+
+ }
+ if (userData != null)
+ {
+ userInfo.PhoneNum = userData?.PhoneNum ?? "";
+ userInfo.Email = userData?.Email ?? "";
+ userInfo.DeviceNumber = userData?.DeviceNumber ?? "";
+ }
+ userInfo.TotalGamingTime = 0;
+ if (userCurrency != null)
+ {
+ userInfo.Diamond = (int)userCurrency.GetUserCurrency(UserCurrencyType.钻石);
+ }
+ return userInfo;
+ }
+
+ ///
+ /// 加载用户缓存
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static UserInfoCache LoadUserInfo(T_User? user = null, T_User_Data? userData = null, Dictionary userCurrency = null)
+ {
+ var userInfo = new UserInfoCache();
+ return LoadUserInfo(userInfo, user, userData, userCurrency);
+ }
+
+
+ ///
+ /// 保存用户缓存
+ ///
+ ///
+ ///
+ public static async Task SaveUserInfoCacheChangesAsync(this CloudGamingBase cloudGamingBase)
+ {
+ var userInfo = cloudGamingBase.UserInfo;
+ var key = GetUserInfoRedisKey(cloudGamingBase.UserInfo.UserId);
+ await cloudGamingBase.RedisCache.StringSetAsync(key, userInfo, TimeSpan.FromHours(1));
+ return userInfo;
+ }
}
}
diff --git a/src/CloudGaming/Code/CloudGaming.Code/Aliyun/AlibabaIdCardVerify.cs b/src/CloudGaming/Code/CloudGaming.Code/Aliyun/AlibabaIdCardVerify.cs
new file mode 100644
index 0000000..813e085
--- /dev/null
+++ b/src/CloudGaming/Code/CloudGaming.Code/Aliyun/AlibabaIdCardVerify.cs
@@ -0,0 +1,105 @@
+using CloudGaming.Code.Contract;
+
+using Newtonsoft.Json;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+using Tea;
+
+using static System.Runtime.InteropServices.JavaScript.JSType;
+
+namespace CloudGaming.Code.Aliyun
+{
+ ///
+ /// 阿里云身份证号验证 AlibabaExtend
+ ///
+ public class AlibabaIdCardVerify(AliyunConfig aliyunConfig) : IIdCardVerify
+ {
+
+ /// Description:
+ ///
+ /// 使用AK&SK初始化账号Client
+ ///
+ ///
+ ///
+ /// Client
+ ///
+ ///
+ /// Exception:
+ /// Exception
+ public AlibabaCloud.SDK.Cloudauth20190307.Client CreateClient()
+ {
+ // 工程代码泄露可能会导致 AccessKey 泄露,并威胁账号下所有资源的安全性。以下代码示例仅供参考。
+ // 建议使用更安全的 STS 方式,更多鉴权访问方式请参见:https://help.aliyun.com/document_detail/378671.html。
+ AlibabaCloud.OpenApiClient.Models.Config config = new AlibabaCloud.OpenApiClient.Models.Config
+ {
+ // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID。
+ AccessKeyId = aliyunConfig.AccessKeyId,
+ // 必填,请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
+ AccessKeySecret = aliyunConfig.AccessKeySecret,
+ };
+ // Endpoint 请参考 https://api.aliyun.com/product/Cloudauth
+ config.Endpoint = "cloudauth.aliyuncs.com";
+ return new AlibabaCloud.SDK.Cloudauth20190307.Client(config);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public async Task<(bool isVerify, string msg)> IdCardVerify(string userName, string idCard)
+ {
+ AlibabaCloud.SDK.Cloudauth20190307.Client client = CreateClient();
+ AlibabaCloud.SDK.Cloudauth20190307.Models.Id2MetaVerifyRequest id2MetaVerifyRequest = new AlibabaCloud.SDK.Cloudauth20190307.Models.Id2MetaVerifyRequest
+ {
+ ParamType = "normal",
+ IdentifyNum = idCard,
+ UserName = userName,
+ };
+ AlibabaCloud.TeaUtil.Models.RuntimeOptions runtime = new AlibabaCloud.TeaUtil.Models.RuntimeOptions();
+ try
+ {
+ // 复制代码运行请自行打印 API 的返回值
+ var obj = await client.Id2MetaVerifyWithOptionsAsync(id2MetaVerifyRequest, runtime);
+ if (obj.Body.ResultObject.BizCode == "1")
+ {
+ return (true, obj.Body.ResultObject.BizCode);
+ }
+ else
+ {
+ return (false, obj.Body.ResultObject.BizCode == "2" ? "核验不一致" : $"{obj.Body.ResultObject.BizCode}_查无记录");
+ }
+ }
+ catch (TeaException error)
+ {
+ // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
+ // 错误 message
+ Console.WriteLine(error.Message);
+ // 诊断地址
+ Console.WriteLine(error.Data["Recommend"]);
+ AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);
+ return (false, error.Message);
+ }
+ catch (Exception _error)
+ {
+ TeaException error = new TeaException(new Dictionary
+ {
+ { "message", _error.Message }
+ });
+ // 此处仅做打印展示,请谨慎对待异常处理,在工程项目中切勿直接忽略异常。
+ // 错误 message
+ Console.WriteLine(error.Message);
+ // 诊断地址
+ Console.WriteLine(error.Data["Recommend"]);
+ AlibabaCloud.TeaUtil.Common.AssertAsString(error.Message);
+ return (false, error.Message);
+ }
+ }
+ }
+}
diff --git a/src/CloudGaming/Code/CloudGaming.Code/AppExtend/CloudGamingBase.cs b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/CloudGamingBase.cs
index e231d32..f758d5c 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/AppExtend/CloudGamingBase.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/AppExtend/CloudGamingBase.cs
@@ -1,5 +1,6 @@
using AutoMapper;
+using CloudGaming.Code.Account;
using CloudGaming.Code.Cache;
using CloudGaming.Code.Config;
using CloudGaming.Code.DataAccess;
@@ -249,15 +250,15 @@ namespace CloudGaming.Code.AppExtend
#endregion
#region 用户信息
- private RequestUserInfo? _userInfo;
+ private RequestUserInfo? _requestUserInfo;
///
/// 用户信息
///
- public RequestUserInfo UserInfo
+ public RequestUserInfo RequestUserInfo
{
get
{
- if (_userInfo == null)
+ if (_requestUserInfo == null)
{
var accessToken = HttpContextAccessor.HttpContext.Request.Headers.GetAuthorization();
if (!string.IsNullOrEmpty(accessToken))
@@ -276,7 +277,7 @@ namespace CloudGaming.Code.AppExtend
}
var nickName = principal.FindFirst("NickName")?.Value;
var userId = int.Parse(userIdStr);
- this._userInfo = new RequestUserInfo()
+ this._requestUserInfo = new RequestUserInfo()
{
UserId = userId,
NickName = nickName
@@ -284,7 +285,7 @@ namespace CloudGaming.Code.AppExtend
}
catch (Exception)
{
- _userInfo = new RequestUserInfo()
+ _requestUserInfo = new RequestUserInfo()
{
UserId = 0
};
@@ -292,14 +293,14 @@ namespace CloudGaming.Code.AppExtend
}
else
{
- _userInfo = new RequestUserInfo()
+ _requestUserInfo = new RequestUserInfo()
{
UserId = 0
};
}
}
- return _userInfo;
+ return _requestUserInfo;
}
}
@@ -310,9 +311,51 @@ namespace CloudGaming.Code.AppExtend
{
get
{
- return UserInfo?.UserId ?? 0;
+ return RequestUserInfo?.UserId ?? 0;
}
}
+
+ private UserInfoCache _userInfo;
+ ///
+ /// 用户信息
+ ///
+ public UserInfoCache UserInfo
+ {
+ get
+ {
+ if (_userInfo == null)
+ {
+ if (_UserId == 0)
+ {
+ _userInfo = new UserInfoCache();
+ }
+
+ _userInfo = _userInfo.GetUserInfo(_UserId, this).Result ?? new UserInfoCache();
+ }
+ return _userInfo;
+ }
+ }
+
+ public async Task GetUserInfoCache()
+ {
+ if (_UserId == 0)
+ {
+ _userInfo = new UserInfoCache();
+ }
+ if (_userInfo == null)
+ {
+ _userInfo = await _userInfo.GetUserInfo(_UserId, this) ?? new UserInfoCache();
+ }
+ return _userInfo;
+ }
#endregion
+
+ ///
+ /// 创建异常
+ ///
+ public Exception CreateException(ResonseCode errorCode, string message)
+ {
+ return MessageBox.Show(errorCode, message);
+ }
}
}
diff --git a/src/CloudGaming/Code/CloudGaming.Code/CloudGaming.Code.csproj b/src/CloudGaming/Code/CloudGaming.Code/CloudGaming.Code.csproj
index 7904fc4..b3eaae3 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/CloudGaming.Code.csproj
+++ b/src/CloudGaming/Code/CloudGaming.Code/CloudGaming.Code.csproj
@@ -10,6 +10,7 @@
+
diff --git a/src/CloudGaming/Code/CloudGaming.Code/Contract/CloudGamingExtend.cs b/src/CloudGaming/Code/CloudGaming.Code/Contract/CloudGamingExtend.cs
new file mode 100644
index 0000000..b2a028a
--- /dev/null
+++ b/src/CloudGaming/Code/CloudGaming.Code/Contract/CloudGamingExtend.cs
@@ -0,0 +1,38 @@
+
+using CloudGaming.Code.Sms;
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using CloudGaming.Code.Aliyun;
+
+namespace CloudGaming.Code.Contract
+{
+ ///
+ ///
+ ///
+ public static class CloudGamingExtend
+ {
+ ///
+ /// 获取短信
+ ///
+ ///
+ ///
+ public static IPhoneNumberVerificationService GetPhoneNumberVerificationService(this AliyunConfig aliyunOssConfig)
+ {
+ return new AlibabaPhoneNumberVerificationService(aliyunOssConfig);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static IIdCardVerify GetIdCardVerify(this CloudGamingBase cloudGamingBase)
+ {
+ return new AlibabaIdCardVerify(cloudGamingBase.AppConfig.AliyunConfig);
+ }
+ }
+}
diff --git a/src/CloudGaming/Code/CloudGaming.Code/Contract/IIdCardVerify.cs b/src/CloudGaming/Code/CloudGaming.Code/Contract/IIdCardVerify.cs
new file mode 100644
index 0000000..9852a3a
--- /dev/null
+++ b/src/CloudGaming/Code/CloudGaming.Code/Contract/IIdCardVerify.cs
@@ -0,0 +1,22 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CloudGaming.Code.Contract
+{
+ ///
+ ///
+ ///
+ public interface IIdCardVerify
+ {
+ ///
+ /// 身份证号验证
+ ///
+ /// 姓名
+ /// 身份证号
+ ///
+ Task<(bool isVerify, string msg)> IdCardVerify(string userName, string idCard);
+ }
+}
diff --git a/src/CloudGaming/Code/CloudGaming.Code/Sms/Contract/IPhoneNumberVerificationService.cs b/src/CloudGaming/Code/CloudGaming.Code/Contract/IPhoneNumberVerificationService.cs
similarity index 93%
rename from src/CloudGaming/Code/CloudGaming.Code/Sms/Contract/IPhoneNumberVerificationService.cs
rename to src/CloudGaming/Code/CloudGaming.Code/Contract/IPhoneNumberVerificationService.cs
index 4765a88..16d1086 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/Sms/Contract/IPhoneNumberVerificationService.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/Contract/IPhoneNumberVerificationService.cs
@@ -4,7 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
-namespace CloudGaming.Code.Sms.Contract
+namespace CloudGaming.Code.Contract
{
///
/// 发送手机短信
diff --git a/src/CloudGaming/Code/CloudGaming.Code/Sms/AlibabaPhoneNumberVerificationService.cs b/src/CloudGaming/Code/CloudGaming.Code/Sms/AlibabaPhoneNumberVerificationService.cs
index ca79868..714f23a 100644
--- a/src/CloudGaming/Code/CloudGaming.Code/Sms/AlibabaPhoneNumberVerificationService.cs
+++ b/src/CloudGaming/Code/CloudGaming.Code/Sms/AlibabaPhoneNumberVerificationService.cs
@@ -1,4 +1,6 @@
-using CloudGaming.Code.Sms.Contract;
+
+
+using CloudGaming.Code.Contract;
using System;
using System.Collections.Generic;
@@ -18,7 +20,7 @@ namespace CloudGaming.Code.Sms
/// Description:
///
- /// 使用AK&SK初始化账号Client
+ /// 使用AK&SK初始化账号Client
///
///
///
@@ -102,15 +104,7 @@ namespace CloudGaming.Code.Sms
///
public static class SmsExtend
{
- ///
- /// 获取短信
- ///
- ///
- ///
- public static IPhoneNumberVerificationService GetPhoneNumberVerificationService(this AliyunConfig aliyunOssConfig)
- {
- return new AlibabaPhoneNumberVerificationService(aliyunOssConfig);
- }
+
}
}
diff --git a/src/CloudGaming/Model/CloudGaming.DtoModel/Account/User/UserActionTypeEnum.cs b/src/CloudGaming/Model/CloudGaming.DtoModel/Account/User/UserActionTypeEnum.cs
new file mode 100644
index 0000000..20b9273
--- /dev/null
+++ b/src/CloudGaming/Model/CloudGaming.DtoModel/Account/User/UserActionTypeEnum.cs
@@ -0,0 +1,35 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CloudGaming.DtoModel.Account.User
+{
+
+ ///
+ ///
+ ///
+ public class UserActionTypeEnum
+ {
+ ///
+ /// 行为类型
+ ///
+ public enum ActionType
+ {
+ ///
+ /// 新人礼包
+ ///
+ 新人礼包 = 1,
+ ///
+ /// 新人第二天登录礼包
+ ///
+ 新人第二天登录礼包 = 2,
+ ///
+ /// 实名认证
+ ///
+ 实名认证 = 3,
+ 换渠道礼包 = 4
+ }
+ }
+}
diff --git a/src/CloudGaming/Model/CloudGaming.DtoModel/Account/User/UserInfoCache.cs b/src/CloudGaming/Model/CloudGaming.DtoModel/Account/User/UserInfoCache.cs
new file mode 100644
index 0000000..e65bb3d
--- /dev/null
+++ b/src/CloudGaming/Model/CloudGaming.DtoModel/Account/User/UserInfoCache.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CloudGaming.DtoModel.Account.User
+{
+ ///
+ /// 用户缓存
+ ///
+ public class UserInfoCache : UserInfo
+ {
+ ///
+ /// 最后一次实名认证时间
+ ///
+ public DateTime? RealNameDateTimeLast { get; set; }
+
+ ///
+ /// 实名认证次数
+ ///
+ public int RealAuthentCount { get; set; }
+
+ ///
+ /// 设备号
+ ///
+ public string DeviceNumber { get; set; }
+ }
+}
diff --git a/src/CloudGaming/Model/CloudGaming.DtoModel/Account/User/UserInfoDto.cs b/src/CloudGaming/Model/CloudGaming.DtoModel/Account/User/UserInfoDto.cs
index 1d9e8c6..e48c6e2 100644
--- a/src/CloudGaming/Model/CloudGaming.DtoModel/Account/User/UserInfoDto.cs
+++ b/src/CloudGaming/Model/CloudGaming.DtoModel/Account/User/UserInfoDto.cs
@@ -11,7 +11,7 @@ namespace CloudGaming.DtoModel.Account.User
///
/// 用户信息
///
- [AutoMap(typeof(UserInfo))]
+ [AutoMap(typeof(UserInfoCache))]
public class UserInfoDto : UserInfo
{
}
diff --git a/src/CloudGaming/Model/CloudGaming.DtoModel/Account/UserRealAuthenticationRequest.cs b/src/CloudGaming/Model/CloudGaming.DtoModel/Account/UserRealAuthenticationRequest.cs
new file mode 100644
index 0000000..8b283c4
--- /dev/null
+++ b/src/CloudGaming/Model/CloudGaming.DtoModel/Account/UserRealAuthenticationRequest.cs
@@ -0,0 +1,28 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CloudGaming.DtoModel.Account
+{
+ ///
+ /// 用户实名认证
+ ///
+ public class UserRealAuthenticationRequest
+ {
+ ///
+ /// 姓名
+ ///
+ public string UserName { get; set; }
+ ///
+ /// 身份证号
+ ///
+ public string IdCard { get; set; }
+ ///
+ /// 设备号
+ ///
+ public string DeviceNumber { get; set; }
+
+ }
+}
diff --git a/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/CloudGamingCBTContext.cs b/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/CloudGamingCBTContext.cs
index 2c953e1..623fa00 100644
--- a/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/CloudGamingCBTContext.cs
+++ b/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/CloudGamingCBTContext.cs
@@ -64,6 +64,11 @@ public partial class CloudGamingCBTContext : DbContext
///
public virtual DbSet T_User_Login_Log { get; set; }
+ ///
+ /// 用户实名认证记录表
+ ///
+ public virtual DbSet T_User_RealAuthentication_Log { get; set; }
+
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{// => optionsBuilder.UseSqlServer("Server=192.168.195.6;Database=CloudGamingCBT;User Id=sa;Password=Dbt@com@123;TrustServerCertificate=true;");
}
@@ -205,6 +210,45 @@ public partial class CloudGamingCBTContext : DbContext
});
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => e.Id).HasName("PK_T_USER_REALAUTHENTICATIONLO");
+
+ entity.ToTable(tb => tb.HasComment("用户实名认证记录表"));
+
+ entity.HasIndex(e => e.UserId, "UserId").IsDescending();
+
+ entity.Property(e => e.Id).HasComment("主键Id");
+ entity.Property(e => e.CreateTime)
+ .HasDefaultValueSql("(getdate())")
+ .HasComment("创建时间")
+ .HasColumnType("datetime");
+ entity.Property(e => e.DeviceNumber)
+ .HasMaxLength(100)
+ .HasComment("设备号");
+ entity.Property(e => e.IdCard)
+ .HasMaxLength(20)
+ .HasDefaultValue("")
+ .HasComment("身份证号")
+ .UseCollation("Chinese_PRC_CI_AS");
+ entity.Property(e => e.IsRewards).HasComment("是否发放奖励");
+ entity.Property(e => e.Message)
+ .HasMaxLength(100)
+ .HasComment("扩展消息");
+ entity.Property(e => e.RealResults)
+ .HasMaxLength(100)
+ .HasComment("认证结果");
+ entity.Property(e => e.UserId)
+ .HasDefaultValueSql("('')")
+ .HasComment("用户id");
+ entity.Property(e => e.UserName)
+ .HasMaxLength(30)
+ .HasDefaultValue("")
+ .HasComment("姓名")
+ .UseCollation("Chinese_PRC_CI_AS");
+
+ });
+
OnModelCreatingPartial(modelBuilder);
}
diff --git a/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/T_User_RealAuthentication_Log.cs b/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/T_User_RealAuthentication_Log.cs
new file mode 100644
index 0000000..ccbbb2d
--- /dev/null
+++ b/src/CloudGaming/Model/CloudGaming.GameModel/Db/Db_Ext/T_User_RealAuthentication_Log.cs
@@ -0,0 +1,56 @@
+using System;
+
+namespace CloudGaming.GameModel.Db.Db_Ext;
+
+///
+/// 用户实名认证记录表
+///
+public partial class T_User_RealAuthentication_Log
+{
+ public T_User_RealAuthentication_Log() { }
+
+ ///
+ /// 主键Id
+ ///
+ public virtual int Id { get; set; }
+
+ ///
+ /// 用户id
+ ///
+ public virtual int UserId { get; set; }
+
+ ///
+ /// 姓名
+ ///
+ public virtual string UserName { get; set; } = null!;
+
+ ///
+ /// 身份证号
+ ///
+ public virtual string IdCard { get; set; } = null!;
+
+ ///
+ /// 创建时间
+ ///
+ public virtual DateTime CreateTime { get; set; }
+
+ ///
+ /// 设备号
+ ///
+ public virtual string? DeviceNumber { get; set; }
+
+ ///
+ /// 是否发放奖励
+ ///
+ public virtual bool IsRewards { get; set; }
+
+ ///
+ /// 认证结果
+ ///
+ public virtual string? RealResults { get; set; }
+
+ ///
+ /// 扩展消息
+ ///
+ public virtual string? Message { get; set; }
+}
diff --git a/src/CloudGaming/Model/CloudGaming.Model/DbSqlServer/Db_User/CloudGamingUserContext.cs b/src/CloudGaming/Model/CloudGaming.Model/DbSqlServer/Db_User/CloudGamingUserContext.cs
index 53f6d01..b3a314b 100644
--- a/src/CloudGaming/Model/CloudGaming.Model/DbSqlServer/Db_User/CloudGamingUserContext.cs
+++ b/src/CloudGaming/Model/CloudGaming.Model/DbSqlServer/Db_User/CloudGamingUserContext.cs
@@ -63,6 +63,11 @@ public partial class CloudGamingUserContext : MultiTenantDbContext//DbContext
///
public virtual DbSet T_User_IntentOrder { get; set; }
+ ///
+ /// 用户设备限制行为日志表
+ ///
+ public virtual DbSet T_User_LimitActionLog { get; set; }
+
///
/// 小程序登录表
///
@@ -228,6 +233,9 @@ public partial class CloudGamingUserContext : MultiTenantDbContext//DbContext
entity.Property(e => e.CreateAt)
.HasComment("创建时间")
.HasColumnType("datetime");
+ entity.Property(e => e.DeviceNumber)
+ .HasMaxLength(255)
+ .HasComment("设备号");
entity.Property(e => e.Email)
.HasMaxLength(255)
.HasComment("邮箱");
@@ -292,6 +300,41 @@ public partial class CloudGamingUserContext : MultiTenantDbContext//DbContext
}
});
+ modelBuilder.Entity(entity =>
+ {
+ entity.HasKey(e => e.Id).HasName("PK_T_USER_LIMITACTIONLOG");
+
+ entity.ToTable(tb => tb.HasComment("用户设备限制行为日志表"));
+
+ entity.Property(e => e.Id).HasComment("自增");
+ entity.Property(e => e.ActionId)
+ .HasMaxLength(100)
+ .HasComment("行为参数")
+ .UseCollation("Chinese_PRC_CI_AS");
+ entity.Property(e => e.ActionType).HasComment("行为类型1新人礼包,2新人第二天登录礼包,3实名认证奖励");
+ entity.Property(e => e.CreateTime)
+ .HasComment("创建时间")
+ .HasColumnType("datetime");
+ entity.Property(e => e.CreateTimeDay).HasComment("创建时间,天");
+ entity.Property(e => e.DeviceNumber)
+ .HasMaxLength(100)
+ .HasComment("设备号");
+ entity.Property(e => e.Extend1)
+ .HasMaxLength(200)
+ .HasComment("扩展字段")
+ .UseCollation("Chinese_PRC_CI_AS");
+ entity.Property(e => e.Ip)
+ .HasMaxLength(100)
+ .HasComment("请求Ip")
+ .UseCollation("Chinese_PRC_CI_AS");
+ entity.Property(e => e.UserId).HasComment("用户Id");
+ //添加全局筛选器
+ if (this.TenantInfo != null)
+ {
+ entity.HasQueryFilter(it => it.TenantId == this.TenantInfo.TenantId);
+ }
+ });
+
modelBuilder.Entity(entity =>
{
entity.HasKey(e => e.Id).HasName("PK__T_User_M__3214EC073889A8B9");
diff --git a/src/CloudGaming/Model/CloudGaming.Model/DbSqlServer/Db_User/T_User_Data.cs b/src/CloudGaming/Model/CloudGaming.Model/DbSqlServer/Db_User/T_User_Data.cs
index d3a3d2b..60d1625 100644
--- a/src/CloudGaming/Model/CloudGaming.Model/DbSqlServer/Db_User/T_User_Data.cs
+++ b/src/CloudGaming/Model/CloudGaming.Model/DbSqlServer/Db_User/T_User_Data.cs
@@ -43,4 +43,9 @@ public partial class T_User_Data: MultiTenantEntity
/// 修改时间
///
public virtual DateTime UpdateAt { get; set; }
+
+ ///
+ /// 设备号
+ ///
+ public virtual string? DeviceNumber { get; set; }
}
diff --git a/src/CloudGaming/Model/CloudGaming.Model/DbSqlServer/Db_User/T_User_LimitActionLog.cs b/src/CloudGaming/Model/CloudGaming.Model/DbSqlServer/Db_User/T_User_LimitActionLog.cs
new file mode 100644
index 0000000..283c594
--- /dev/null
+++ b/src/CloudGaming/Model/CloudGaming.Model/DbSqlServer/Db_User/T_User_LimitActionLog.cs
@@ -0,0 +1,56 @@
+using System;
+
+namespace CloudGaming.Model.DbSqlServer.Db_User;
+
+///
+/// 用户设备限制行为日志表
+///
+public partial class T_User_LimitActionLog: MultiTenantEntity
+{
+ public T_User_LimitActionLog() { }
+
+ ///
+ /// 自增
+ ///
+ public virtual int Id { get; set; }
+
+ ///
+ /// 用户Id
+ ///
+ public virtual int UserId { get; set; }
+
+ ///
+ /// 请求Ip
+ ///
+ public virtual string? Ip { get; set; }
+
+ ///
+ /// 行为类型1新人礼包,2新人第二天登录礼包,3实名认证奖励
+ ///
+ public virtual int ActionType { get; set; }
+
+ ///
+ /// 行为参数
+ ///
+ public virtual string? ActionId { get; set; }
+
+ ///
+ /// 创建时间
+ ///
+ public virtual DateTime CreateTime { get; set; }
+
+ ///
+ /// 创建时间,天
+ ///
+ public virtual int CreateTimeDay { get; set; }
+
+ ///
+ /// 设备号
+ ///
+ public virtual string? DeviceNumber { get; set; }
+
+ ///
+ /// 扩展字段
+ ///
+ public virtual string? Extend1 { get; set; }
+}
diff --git a/src/CloudGaming/Utile/HuanMeng.DotNetCore/Utility/DateTimeExtensions.cs b/src/CloudGaming/Utile/HuanMeng.DotNetCore/Utility/DateTimeExtensions.cs
index deb92e9..72b700c 100644
--- a/src/CloudGaming/Utile/HuanMeng.DotNetCore/Utility/DateTimeExtensions.cs
+++ b/src/CloudGaming/Utile/HuanMeng.DotNetCore/Utility/DateTimeExtensions.cs
@@ -10,7 +10,7 @@ namespace HuanMeng.DotNetCore.Utility
public static class DateTimeExtensions
{
///
- /// 获取时间戳,秒
+ /// 获取时间戳,秒
///
///
///
diff --git a/src/CloudGaming/Utile/HuanMeng.DotNetCore/Utility/OtherExtensions.cs b/src/CloudGaming/Utile/HuanMeng.DotNetCore/Utility/OtherExtensions.cs
new file mode 100644
index 0000000..06338e4
--- /dev/null
+++ b/src/CloudGaming/Utile/HuanMeng.DotNetCore/Utility/OtherExtensions.cs
@@ -0,0 +1,133 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Threading.Tasks;
+
+namespace HuanMeng.DotNetCore.Utility
+{
+ ///
+ /// 其它扩展类
+ ///
+ public static class OtherExtensions
+ {
+ ///
+ /// 验证身份证号是否正确
+ ///
+ ///
+ ///
+
+ public static bool ValidateIDCard(string idNumber)
+ {
+ if (string.IsNullOrEmpty(idNumber))
+ {
+ return false;
+ }
+
+ // 验证长度
+ if (idNumber.Length != 18)
+ {
+ return false;
+ }
+
+ // 验证格式
+ Regex regex = new Regex(@"^\d{17}(\d|X)$");
+ if (!regex.IsMatch(idNumber))
+ {
+ return false;
+ }
+
+ // 验证校验码
+ return ValidateCheckDigit(idNumber);
+ }
+ ///
+ /// 验证校验码
+ ///
+ ///
+ ///
+
+ private static bool ValidateCheckDigit(string idNumber)
+ {
+ // 加权因子
+ int[] weights = { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2 };
+ // 校验码
+ char[] checkDigits = { '1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };
+
+ int sum = 0;
+ for (int i = 0; i < 17; i++)
+ {
+ sum += (idNumber[i] - '0') * weights[i];
+ }
+
+ int mod = sum % 11;
+ return idNumber[17] == checkDigits[mod];
+ }
+
+ ///
+ /// 根据身份证号计算年龄、性别、生日
+ ///
+ /// 身份证号
+ ///
+ public static (bool verify, int age, string sex, string birthday) GetIDCardBirthdayAgeSex(string identityCard)
+ {
+ var birthday = "";
+ var age = 0;
+ var sex = "";
+ if (string.IsNullOrEmpty(identityCard))
+ {
+ return (false, 0, "", "");
+ }
+ else
+ {
+ if (identityCard.Length != 15 && identityCard.Length != 18)//身份证号码只能为15位或18位其它不合法
+ {
+ return (false, 0, "", "");
+ }
+ }
+
+ birthday = "";
+ string strSex = string.Empty;
+ if (identityCard.Length == 18)//处理18位的身份证号码从号码中得到生日和性别代码
+ {
+ birthday = identityCard.Substring(6, 4) + "-" + identityCard.Substring(10, 2) + "-" + identityCard.Substring(12, 2);
+ strSex = identityCard.Substring(14, 3);
+ }
+ if (identityCard.Length == 15)
+ {
+ birthday = "19" + identityCard.Substring(6, 2) + "-" + identityCard.Substring(8, 2) + "-" + identityCard.Substring(10, 2);
+ strSex = identityCard.Substring(12, 3);
+ }
+
+ age = CalculateAge(birthday);//根据生日计算年龄
+
+ if (int.Parse(strSex) % 2 == 0)//性别代码为偶数是女性奇数为男性
+ {
+ sex = "女";
+ }
+ else
+ {
+ sex = "男";
+ }
+ return (true, age, sex, birthday);
+ }
+
+ ///
+ /// 根据出生日期,计算精确的年龄
+ ///
+ /// 生日
+ ///
+ public static int CalculateAge(string birthDay)
+ {
+ DateTime birthDate = DateTime.Parse(birthDay);
+ DateTime nowDateTime = DateTime.Now;
+ int age = nowDateTime.Year - birthDate.Year;
+ //再考虑月、天的因素
+ if (nowDateTime.Month < birthDate.Month || (nowDateTime.Month == birthDate.Month && nowDateTime.Day < birthDate.Day))
+ {
+ age--;
+ }
+ return age;
+ }
+ }
+}