小程序登录注册,工具类接口统一
This commit is contained in:
parent
16b000add2
commit
87a8c989bf
@ -2,54 +2,29 @@ using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace YD_Event.Application.Client.Dtos;
|
||||
|
||||
public class WeChatLoginInput
|
||||
/// <summary>
|
||||
/// 小程序登录输入参数
|
||||
/// </summary>
|
||||
public class MiniProgramLoginInput
|
||||
{
|
||||
/// <summary>
|
||||
/// 微信临时授权码
|
||||
/// 手机号
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "code不能为空")]
|
||||
public string Code { get; set; }
|
||||
[Required(ErrorMessage = "手机号不能为空")]
|
||||
[RegularExpression(@"^1[3456789]\d{9}$", ErrorMessage = "手机号格式不正确")]
|
||||
public string Mobile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 加密数据
|
||||
/// 密码
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "encryptedData不能为空")]
|
||||
public string EncryptedData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始向量
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "iv不能为空")]
|
||||
public string Iv { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 原始数据
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "rawData不能为空")]
|
||||
public string RawData { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 签名
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "signature不能为空")]
|
||||
public string Signature { get; set; }
|
||||
public string Password { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 微信登录输出参数
|
||||
/// 小程序登录输出参数
|
||||
/// </summary>
|
||||
public class WeChatLoginOutput
|
||||
public class MiniProgramLoginOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// OpenId
|
||||
/// </summary>
|
||||
public string Openid { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 会话密钥
|
||||
/// </summary>
|
||||
public string SessionKey { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 访问令牌
|
||||
/// </summary>
|
||||
@ -61,7 +36,7 @@ public class WeChatLoginOutput
|
||||
public string RefreshToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 过期时间
|
||||
/// 过期时间(秒)
|
||||
/// </summary>
|
||||
public int ExpiresIn { get; set; }
|
||||
|
||||
@ -72,50 +47,47 @@ public class WeChatLoginOutput
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 微信注册输入参数
|
||||
/// 小程序注册输入参数
|
||||
/// </summary>
|
||||
public class WeChatRegisterInput
|
||||
public class MiniProgramRegisterInput
|
||||
{
|
||||
/// <summary>
|
||||
/// OpenId
|
||||
/// 手机号(必填)
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "openid不能为空")]
|
||||
public string Openid { get; set; }
|
||||
[Required(ErrorMessage = "手机号不能为空")]
|
||||
[RegularExpression(@"^1[3456789]\d{9}$", ErrorMessage = "手机号格式不正确")]
|
||||
public string Mobile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 加密数据
|
||||
/// 密码(必填)
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "encryptedData不能为空")]
|
||||
public string EncryptedData { get; set; }
|
||||
[Required(ErrorMessage = "密码不能为空")]
|
||||
[StringLength(32, MinimumLength = 6, ErrorMessage = "密码长度必须在6-32位之间")]
|
||||
public string Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始向量
|
||||
/// 验证码(必填)
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "iv不能为空")]
|
||||
public string Iv { get; set; }
|
||||
[Required(ErrorMessage = "验证码不能为空")]
|
||||
public string VerificationCode { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 原始数据
|
||||
/// 昵称(可选)
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "rawData不能为空")]
|
||||
public string RawData { get; set; }
|
||||
[StringLength(64, ErrorMessage = "昵称长度不能超过64个字符")]
|
||||
public string NickName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 签名
|
||||
/// 头像(可选)
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "signature不能为空")]
|
||||
public string Signature { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 邀请码 (可选)
|
||||
/// </summary>
|
||||
public string? InviteCode { get; set; }
|
||||
[StringLength(512, ErrorMessage = "头像URL长度不能超过512个字符")]
|
||||
public string Avatar { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 微信注册输出参数
|
||||
/// 小程序注册输出参数
|
||||
/// </summary>
|
||||
public class WeChatRegisterOutput
|
||||
public class MiniProgramRegisterOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// 用户ID
|
||||
@ -123,14 +95,14 @@ public class WeChatRegisterOutput
|
||||
public long UserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 昵称
|
||||
/// 手机号
|
||||
/// </summary>
|
||||
public string Nickname { get; set; }
|
||||
public string Mobile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 头像URL
|
||||
/// 昵称
|
||||
/// </summary>
|
||||
public string AvatarUrl { get; set; }
|
||||
public string NickName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 注册时间
|
||||
@ -139,123 +111,27 @@ public class WeChatRegisterOutput
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 微信重置密码输入参数
|
||||
/// 小程序重置密码输入参数
|
||||
/// </summary>
|
||||
public class WeChatResetPasswordInput
|
||||
public class MiniProgramResetPasswordInput
|
||||
{
|
||||
/// <summary>
|
||||
/// OpenId
|
||||
/// 手机号(必填)
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "openid不能为空")]
|
||||
public string Openid { get; set; }
|
||||
[Required(ErrorMessage = "手机号不能为空")]
|
||||
[RegularExpression(@"^1[3456789]\d{9}$", ErrorMessage = "手机号格式不正确")]
|
||||
public string Mobile { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 加密数据
|
||||
/// 新密码(必填)
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "encryptedData不能为空")]
|
||||
public string EncryptedData { get; set; }
|
||||
[Required(ErrorMessage = "新密码不能为空")]
|
||||
[StringLength(32, MinimumLength = 6, ErrorMessage = "密码长度必须在6-32位之间")]
|
||||
public string NewPassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 初始向量
|
||||
/// 验证码(必填)
|
||||
/// </summary>
|
||||
[Required(ErrorMessage = "iv不能为空")]
|
||||
public string Iv { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 邮箱 (可选)
|
||||
/// </summary>
|
||||
public string? Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 短信验证码 (可选)
|
||||
/// </summary>
|
||||
public string? SmsCode { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 微信重置密码输出参数
|
||||
/// </summary>
|
||||
public class WeChatResetPasswordOutput
|
||||
{
|
||||
/// <summary>
|
||||
/// 重置令牌
|
||||
/// </summary>
|
||||
public string ResetToken { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 过期时间
|
||||
/// </summary>
|
||||
public DateTime ExpireTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 发送渠道 (email/sms)
|
||||
/// </summary>
|
||||
public string SendChannel { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 微信用户信息
|
||||
/// </summary>
|
||||
public class WeChatUserInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// OpenId
|
||||
/// </summary>
|
||||
public string OpenId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 昵称
|
||||
/// </summary>
|
||||
public string NickName { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 性别
|
||||
/// </summary>
|
||||
public int Gender { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 城市
|
||||
/// </summary>
|
||||
public string City { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 省份
|
||||
/// </summary>
|
||||
public string Province { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 国家
|
||||
/// </summary>
|
||||
public string Country { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 头像URL
|
||||
/// </summary>
|
||||
public string AvatarUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// UnionId
|
||||
/// </summary>
|
||||
public string UnionId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 水印
|
||||
/// </summary>
|
||||
public Watermark Watermark { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 水印信息
|
||||
/// </summary>
|
||||
public class Watermark
|
||||
{
|
||||
/// <summary>
|
||||
/// 时间戳
|
||||
/// </summary>
|
||||
public long Timestamp { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// AppId
|
||||
/// </summary>
|
||||
public string Appid { get; set; }
|
||||
[Required(ErrorMessage = "验证码不能为空")]
|
||||
public string VerificationCode { get; set; }
|
||||
}
|
||||
|
||||
@ -1,13 +1,6 @@
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using Microsoft.IdentityModel.Tokens;
|
||||
using System.IdentityModel.Tokens.Jwt;
|
||||
using YD_Event.Application.Client.Dtos;
|
||||
using YD_Event.Core.Infrastructure.WeChat;
|
||||
using YD_Event.Application.Auth;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace YD_Event.Application.Client;
|
||||
|
||||
@ -17,33 +10,21 @@ namespace YD_Event.Application.Client;
|
||||
[ApiDescriptionSettings("微信小程序接口")]
|
||||
public class OAuthController : IDynamicApiController
|
||||
{
|
||||
private readonly WeChatService _weChatTool;
|
||||
private readonly ISqlSugarRepository<AuthAccount> _accountRepository;
|
||||
private readonly ISqlSugarRepository<YD_Event.Core.Entities.AppUser> _appUserRepository;
|
||||
private readonly ISqlSugarRepository<SysRole> _roleRepository;
|
||||
private readonly ISqlSugarRepository<SysUserRole> _userRoleRepository;
|
||||
private readonly IEasyCachingProvider _easyCachingProvider;
|
||||
private readonly IMemoryCache _memoryCache;
|
||||
private readonly IIdGenerator _idGenerator;
|
||||
private readonly ILogger<OAuthController> _logger;
|
||||
|
||||
private const string SessionKeyCachePrefix = "wechat_session_";
|
||||
private const string SmsCodeCachePrefix = "sms:code:";
|
||||
|
||||
public OAuthController(
|
||||
WeChatService weChatTool,
|
||||
ISqlSugarRepository<AuthAccount> accountRepository,
|
||||
ISqlSugarRepository<YD_Event.Core.Entities.AppUser> appUserRepository,
|
||||
ISqlSugarRepository<SysRole> roleRepository,
|
||||
ISqlSugarRepository<SysUserRole> userRoleRepository,
|
||||
IEasyCachingProvider easyCachingProvider,
|
||||
IMemoryCache memoryCache,
|
||||
IIdGenerator idGenerator,
|
||||
ILogger<OAuthController> logger)
|
||||
{
|
||||
_weChatTool = weChatTool;
|
||||
_accountRepository = accountRepository;
|
||||
_appUserRepository = appUserRepository;
|
||||
_roleRepository = roleRepository;
|
||||
_userRoleRepository = userRoleRepository;
|
||||
_easyCachingProvider = easyCachingProvider;
|
||||
_memoryCache = memoryCache;
|
||||
_idGenerator = idGenerator;
|
||||
_logger = logger;
|
||||
}
|
||||
@ -55,52 +36,59 @@ public class OAuthController : IDynamicApiController
|
||||
/// <returns></returns>
|
||||
[HttpPost("login")]
|
||||
[AllowAnonymous]
|
||||
public async Task<WeChatLoginOutput> Login([FromBody] WeChatLoginInput input)
|
||||
public async Task<MiniProgramLoginOutput> Login([FromBody] MiniProgramLoginInput input)
|
||||
{
|
||||
// 1. code2Session
|
||||
var sessionResult = await _weChatTool.Code2Session(input.Code);
|
||||
string openid = sessionResult.OpenId;
|
||||
string sessionKey = sessionResult.SessionKey;
|
||||
|
||||
// 缓存 session_key,用于后续解密
|
||||
await _easyCachingProvider.SetAsync($"{SessionKeyCachePrefix}{openid}", sessionKey, TimeSpan.FromHours(2));
|
||||
|
||||
// 2. 校验签名 (可选,根据业务严谨性)
|
||||
// var signature2 = Hash(input.RawData + sessionKey);
|
||||
// if (signature2 != input.Signature) throw Oops.Bah("签名校验失败");
|
||||
|
||||
// 3. 查找用户
|
||||
var account = await _accountRepository.GetFirstAsync(x => x.OAuthId == openid && x.Type == "WeChat");
|
||||
|
||||
string accessToken = null;
|
||||
string refreshToken = null;
|
||||
object userInfo = null;
|
||||
int expiresIn = 7200;
|
||||
|
||||
if (account != null)
|
||||
if (string.IsNullOrEmpty(input.Password) && string.IsNullOrEmpty(input.VerificationCode))
|
||||
{
|
||||
// 生成 Token
|
||||
(accessToken, refreshToken) = GenerateTokens(account);
|
||||
|
||||
// 获取用户信息
|
||||
var appUser = await _appUserRepository.GetFirstAsync(x => x.UserId == account.Id);
|
||||
if (appUser != null)
|
||||
throw Oops.Bah("密码和验证码至少提供一个");
|
||||
}
|
||||
|
||||
var appUser = await _appUserRepository.GetFirstAsync(x => x.Mobile == input.Mobile);
|
||||
if (appUser == null)
|
||||
{
|
||||
throw Oops.Bah("用户不存在,请先注册");
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(input.Password))
|
||||
{
|
||||
if (string.IsNullOrEmpty(appUser.Password))
|
||||
{
|
||||
userInfo = new { appUser.Name, appUser.Id, appUser.Mobile, appUser.Avatar, appUser.NickName };
|
||||
throw Oops.Bah("该用户未设置密码,请使用验证码登录");
|
||||
}
|
||||
else
|
||||
var encryptedPassword = MD5Encryption.Encrypt($"{_idGenerator.Encode(appUser.Id)}{input.Password}");
|
||||
if (appUser.Password != encryptedPassword)
|
||||
{
|
||||
userInfo = new { account.Name, account.Avatar };
|
||||
throw Oops.Bah("密码错误");
|
||||
}
|
||||
}
|
||||
|
||||
return new WeChatLoginOutput
|
||||
if (!string.IsNullOrEmpty(input.VerificationCode))
|
||||
{
|
||||
var cacheKey = $"{SmsCodeCachePrefix}{input.Mobile}";
|
||||
string cachedCode = null;
|
||||
if (!_memoryCache.TryGetValue(cacheKey, out cachedCode) || cachedCode != input.VerificationCode)
|
||||
{
|
||||
throw Oops.Bah("验证码错误或已过期");
|
||||
}
|
||||
_memoryCache.Remove(cacheKey);
|
||||
}
|
||||
|
||||
(string accessToken, string refreshToken) = GenerateTokens(appUser);
|
||||
|
||||
var userInfo = new
|
||||
{
|
||||
appUser.Name,
|
||||
appUser.Id,
|
||||
appUser.Mobile,
|
||||
appUser.Avatar,
|
||||
appUser.NickName
|
||||
};
|
||||
|
||||
return new MiniProgramLoginOutput
|
||||
{
|
||||
Openid = openid,
|
||||
SessionKey = sessionKey, // 需求要求返回
|
||||
AccessToken = accessToken,
|
||||
RefreshToken = refreshToken,
|
||||
ExpiresIn = expiresIn,
|
||||
ExpiresIn = 7200,
|
||||
UserInfo = userInfo
|
||||
};
|
||||
}
|
||||
@ -113,204 +101,95 @@ public class OAuthController : IDynamicApiController
|
||||
[HttpPost("register")]
|
||||
[AllowAnonymous]
|
||||
[UnitOfWork]
|
||||
public async Task<WeChatRegisterOutput> Register([FromBody] WeChatRegisterInput input)
|
||||
public async Task<MiniProgramRegisterOutput> Register([FromBody] MiniProgramRegisterInput input)
|
||||
{
|
||||
// 1. 获取 session_key
|
||||
var cacheKey = $"{SessionKeyCachePrefix}{input.Openid}";
|
||||
var sessionKeyCache = await _easyCachingProvider.GetAsync<string>(cacheKey);
|
||||
if (!sessionKeyCache.HasValue) throw Oops.Bah("SessionKey已过期,请重新登录");
|
||||
string sessionKey = sessionKeyCache.Value;
|
||||
|
||||
// 2. 解密用户信息
|
||||
string json = DecryptWeChatData(input.EncryptedData, sessionKey, input.Iv);
|
||||
var wxUser = JsonConvert.DeserializeObject<WeChatUserInfo>(json);
|
||||
if (wxUser == null) throw Oops.Bah("解密用户信息失败");
|
||||
|
||||
// 验证 watermark
|
||||
var configAppId = App.Configuration["WeChat:AppId"];
|
||||
if (!string.IsNullOrEmpty(configAppId) && wxUser.Watermark?.Appid != configAppId)
|
||||
var cacheKey = $"{SmsCodeCachePrefix}{input.Mobile}";
|
||||
string cachedCode = null;
|
||||
if (!_memoryCache.TryGetValue(cacheKey, out cachedCode) || cachedCode != input.VerificationCode)
|
||||
{
|
||||
// 仅记录警告,防止配置不一致导致注册失败
|
||||
_logger.LogWarning($"Watermark AppId mismatch: {wxUser.Watermark?.Appid} vs {configAppId}");
|
||||
throw Oops.Bah("验证码错误或已过期");
|
||||
}
|
||||
_memoryCache.Remove(cacheKey);
|
||||
|
||||
if (await _appUserRepository.IsAnyAsync(x => x.Mobile == input.Mobile))
|
||||
{
|
||||
throw Oops.Bah("该手机号已注册");
|
||||
}
|
||||
|
||||
// 3. 写入 AuthAccount
|
||||
// 检查是否已存在
|
||||
if (await _accountRepository.IsAnyAsync(x => x.OAuthId == input.Openid && x.Type == "WeChat"))
|
||||
{
|
||||
throw Oops.Bah("该用户已注册");
|
||||
}
|
||||
|
||||
long accountId = _idGenerator.NewLong();
|
||||
var account = new AuthAccount
|
||||
{
|
||||
Id = accountId,
|
||||
OAuthId = input.Openid,
|
||||
Type = "WeChat",
|
||||
Name = wxUser.NickName,
|
||||
Avatar = wxUser.AvatarUrl,
|
||||
Gender = (Gender)wxUser.Gender, // 假设 Gender 枚举兼容
|
||||
CreatedTime = DateTime.Now,
|
||||
CreatedUserId = accountId // 自指
|
||||
};
|
||||
await _accountRepository.InsertAsync(account);
|
||||
|
||||
// 4. 写入 AppUser (Profile)
|
||||
long appUserId = _idGenerator.NewLong();
|
||||
var encryptedPassword = MD5Encryption.Encrypt($"{_idGenerator.Encode(appUserId)}{input.Password}");
|
||||
|
||||
var appUser = new YD_Event.Core.Entities.AppUser
|
||||
{
|
||||
Id = appUserId,
|
||||
UserId = accountId,
|
||||
Name = wxUser.NickName,
|
||||
NickName = wxUser.NickName,
|
||||
Avatar = wxUser.AvatarUrl,
|
||||
Gender = (Gender)wxUser.Gender,
|
||||
PersonType = PersonType.User, // 普通用户
|
||||
Name = input.NickName ?? input.Mobile,
|
||||
NickName = input.NickName,
|
||||
Avatar = input.Avatar,
|
||||
Gender = Gender.Unknown,
|
||||
Mobile = input.Mobile,
|
||||
Password = encryptedPassword,
|
||||
PersonType = PersonType.User,
|
||||
Status = AvailabilityStatus.Enable,
|
||||
AuditStatus = AuditStatus.Pass,
|
||||
CreatedTime = DateTime.Now,
|
||||
CreatedUserId = accountId
|
||||
CreatedUserId = appUserId
|
||||
};
|
||||
await _appUserRepository.InsertAsync(appUser);
|
||||
|
||||
// 5. 初始化默认角色
|
||||
// 查找默认角色,假设为 "OrdinaryUser" 或 "User"
|
||||
var defaultRole = await _roleRepository.GetFirstAsync(x => x.Code == "User" || x.Code == "OrdinaryUser");
|
||||
if (defaultRole == null)
|
||||
return new MiniProgramRegisterOutput
|
||||
{
|
||||
// 如果不存在,创建一个默认角色
|
||||
defaultRole = new SysRole
|
||||
{
|
||||
Id = _idGenerator.NewLong(),
|
||||
Name = "普通用户",
|
||||
Code = "User",
|
||||
Status = AvailabilityStatus.Enable,
|
||||
CreatedTime = DateTime.Now
|
||||
};
|
||||
await _roleRepository.InsertAsync(defaultRole);
|
||||
}
|
||||
|
||||
// 绑定角色 (这里是 AppUser 还是 AuthAccount 绑定角色? SysUserRole 关联 UserId,通常指 AuthAccount.Id 或 SysUser.Id)
|
||||
// 假设 SysUserRole.UserId 对应 AuthAccount.Id (因为 AuthAccount 是登录主体)
|
||||
await _userRoleRepository.InsertAsync(new SysUserRole
|
||||
{
|
||||
Id = _idGenerator.NewLong(),
|
||||
UserId = accountId,
|
||||
RoleId = defaultRole.Id,
|
||||
CreatedTime = DateTime.Now
|
||||
});
|
||||
|
||||
return new WeChatRegisterOutput
|
||||
{
|
||||
UserId = accountId,
|
||||
Nickname = account.Name,
|
||||
AvatarUrl = account.Avatar,
|
||||
RegisterTime = account.CreatedTime
|
||||
UserId = appUser.Id,
|
||||
Mobile = appUser.Mobile,
|
||||
NickName = appUser.NickName,
|
||||
RegisterTime = appUser.CreatedTime
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 找回密码接口
|
||||
/// 重置密码接口
|
||||
/// </summary>
|
||||
/// <param name="input"></param>
|
||||
/// <returns></returns>
|
||||
[HttpPost("reset-password")]
|
||||
[AllowAnonymous]
|
||||
public async Task<WeChatResetPasswordOutput> ResetPassword([FromBody] WeChatResetPasswordInput input)
|
||||
public async Task ResetPassword([FromBody] MiniProgramResetPasswordInput input)
|
||||
{
|
||||
// 1. 获取 session_key
|
||||
var cacheKey = $"{SessionKeyCachePrefix}{input.Openid}";
|
||||
var sessionKeyCache = await _easyCachingProvider.GetAsync<string>(cacheKey);
|
||||
if (!sessionKeyCache.HasValue) throw Oops.Bah("SessionKey已过期,请重新登录");
|
||||
string sessionKey = sessionKeyCache.Value;
|
||||
|
||||
// 2. 验证微信身份 (尝试解密)
|
||||
try
|
||||
var cacheKey = $"{SmsCodeCachePrefix}{input.Mobile}";
|
||||
string cachedCode = null;
|
||||
if (!_memoryCache.TryGetValue(cacheKey, out cachedCode) || cachedCode != input.VerificationCode)
|
||||
{
|
||||
string json = DecryptWeChatData(input.EncryptedData, sessionKey, input.Iv);
|
||||
var wxUser = JsonConvert.DeserializeObject<WeChatUserInfo>(json);
|
||||
if (wxUser.OpenId != input.Openid) throw Oops.Bah("身份验证失败: OpenId不匹配");
|
||||
throw Oops.Bah("验证码错误或已过期");
|
||||
}
|
||||
catch (Exception ex)
|
||||
_memoryCache.Remove(cacheKey);
|
||||
|
||||
var appUser = await _appUserRepository.GetFirstAsync(x => x.Mobile == input.Mobile);
|
||||
if (appUser == null)
|
||||
{
|
||||
_logger.LogError(ex, "ResetPassword Decrypt Failed");
|
||||
throw Oops.Bah("身份验证失败");
|
||||
throw Oops.Bah("用户不存在");
|
||||
}
|
||||
|
||||
// 3. 生成一次性 Token
|
||||
string resetToken = Guid.NewGuid().ToString("N");
|
||||
|
||||
// 4. 发送邮件/短信 (Mock)
|
||||
string sendChannel = "none";
|
||||
if (!string.IsNullOrEmpty(input.Email))
|
||||
{
|
||||
// Mock send email
|
||||
_logger.LogInformation($"Send Reset Token {resetToken} to Email {input.Email}");
|
||||
sendChannel = "email";
|
||||
}
|
||||
else if (!string.IsNullOrEmpty(input.SmsCode))
|
||||
{
|
||||
// Verify Sms Code (Mock)
|
||||
// Mock send sms
|
||||
_logger.LogInformation($"Verify SMS Code {input.SmsCode} and generate token");
|
||||
sendChannel = "sms";
|
||||
}
|
||||
var encryptedPassword = MD5Encryption.Encrypt($"{_idGenerator.Encode(appUser.Id)}{input.NewPassword}");
|
||||
appUser.Password = encryptedPassword;
|
||||
appUser.UpdatedTime = DateTime.Now;
|
||||
appUser.UpdatedUserId = appUser.Id;
|
||||
|
||||
return new WeChatResetPasswordOutput
|
||||
{
|
||||
ResetToken = resetToken,
|
||||
ExpireTime = DateTime.Now.AddMinutes(15),
|
||||
SendChannel = sendChannel
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// AES-128-CBC 解密
|
||||
/// </summary>
|
||||
private string DecryptWeChatData(string encryptedData, string sessionKey, string iv)
|
||||
{
|
||||
try
|
||||
{
|
||||
byte[] encryptedBytes = Convert.FromBase64String(encryptedData);
|
||||
byte[] keyBytes = Convert.FromBase64String(sessionKey);
|
||||
byte[] ivBytes = Convert.FromBase64String(iv);
|
||||
|
||||
using var aes = Aes.Create();
|
||||
aes.KeySize = 128;
|
||||
aes.BlockSize = 128;
|
||||
aes.Mode = CipherMode.CBC;
|
||||
aes.Padding = PaddingMode.PKCS7;
|
||||
aes.Key = keyBytes;
|
||||
aes.IV = ivBytes;
|
||||
|
||||
using var decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
|
||||
using var ms = new MemoryStream(encryptedBytes);
|
||||
using var cs = new CryptoStream(ms, decryptor, CryptoStreamMode.Read);
|
||||
using var sr = new StreamReader(cs);
|
||||
return sr.ReadToEnd();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "AES Decrypt Error");
|
||||
throw Oops.Bah("数据解密失败");
|
||||
}
|
||||
await _appUserRepository.UpdateAsync(appUser);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成自定义 Token
|
||||
/// </summary>
|
||||
private (string AccessToken, string RefreshToken) GenerateTokens(AuthAccount account)
|
||||
private (string AccessToken, string RefreshToken) GenerateTokens(YD_Event.Core.Entities.AppUser appUser)
|
||||
{
|
||||
long uniqueId = _idGenerator.NewLong();
|
||||
string accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>()
|
||||
{
|
||||
[AuthClaimsConst.AuthIdKey] = account.Id,
|
||||
[AuthClaimsConst.AccountKey] = account.OAuthId,
|
||||
[AuthClaimsConst.AuthIdKey] = appUser.Id,
|
||||
[AuthClaimsConst.AccountKey] = appUser.Mobile,
|
||||
[AuthClaimsConst.UuidKey] = uniqueId,
|
||||
[AuthClaimsConst.AuthPlatformTypeKey] = AuthPlatformType.WeChatApplet
|
||||
});
|
||||
|
||||
// 获取刷新 token
|
||||
string refreshToken = JWTEncryption.GenerateRefreshToken(accessToken);
|
||||
|
||||
return (accessToken, refreshToken);
|
||||
|
||||
@ -8,6 +8,4 @@ public class SendVerificationCodeInput
|
||||
[Required(ErrorMessage = "手机号不能为空")]
|
||||
[RegularExpression(@"^1[3456789]\d{9}$", ErrorMessage = "手机号格式不正确")]
|
||||
public string Phone { get; set; } = null!;
|
||||
|
||||
public string? Code { get; set; }
|
||||
}
|
||||
|
||||
@ -16,7 +16,7 @@ public class SmsService : IDynamicApiController, ITransient
|
||||
_memoryCache = memoryCache;
|
||||
}
|
||||
|
||||
[HttpPost("sms/sendVerificationCode")]
|
||||
[HttpPost("sendVerificationCode")]
|
||||
[DisplayName("发送短信验证码")]
|
||||
[AllowAnonymous]
|
||||
public async Task SendVerificationCode([FromBody] SendVerificationCodeInput input)
|
||||
@ -27,7 +27,7 @@ public class SmsService : IDynamicApiController, ITransient
|
||||
throw Oops.Bah("发送太频繁,请稍后再试");
|
||||
}
|
||||
|
||||
string code = input.Code ?? new Random().Next(100000, 999999).ToString();
|
||||
string code = new Random().Next(100000, 999999).ToString();
|
||||
|
||||
await _smsService.SendVerificationCode(input.Phone, code);
|
||||
|
||||
|
||||
@ -360,7 +360,7 @@ public class UserEventRegistrationService : IDynamicApiController, ITransient
|
||||
Gender = member.Gender,
|
||||
IdCard = member.IdCardNumber,
|
||||
Phone = member.Mobile,
|
||||
Age = member.Age,
|
||||
Age = member.Age ?? 0,
|
||||
BirthDate = member.BirthDate ?? DateTime.MinValue,
|
||||
PersonType = PersonType.Athlete,
|
||||
CreatedUserId = userId,
|
||||
|
||||
@ -2080,239 +2080,124 @@
|
||||
拒绝/取消原因
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatLoginInput.Code">
|
||||
<member name="T:YD_Event.Application.Client.Dtos.MiniProgramLoginInput">
|
||||
<summary>
|
||||
微信临时授权码
|
||||
小程序登录输入参数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatLoginInput.EncryptedData">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramLoginInput.Mobile">
|
||||
<summary>
|
||||
加密数据
|
||||
手机号
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatLoginInput.Iv">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramLoginInput.Password">
|
||||
<summary>
|
||||
初始向量
|
||||
密码(可选,与验证码至少提供一个)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatLoginInput.RawData">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramLoginInput.VerificationCode">
|
||||
<summary>
|
||||
原始数据
|
||||
验证码(可选,与密码至少提供一个)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatLoginInput.Signature">
|
||||
<member name="T:YD_Event.Application.Client.Dtos.MiniProgramLoginOutput">
|
||||
<summary>
|
||||
签名
|
||||
小程序登录输出参数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Client.Dtos.WeChatLoginOutput">
|
||||
<summary>
|
||||
微信登录输出参数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatLoginOutput.Openid">
|
||||
<summary>
|
||||
OpenId
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatLoginOutput.SessionKey">
|
||||
<summary>
|
||||
会话密钥
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatLoginOutput.AccessToken">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramLoginOutput.AccessToken">
|
||||
<summary>
|
||||
访问令牌
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatLoginOutput.RefreshToken">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramLoginOutput.RefreshToken">
|
||||
<summary>
|
||||
刷新令牌
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatLoginOutput.ExpiresIn">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramLoginOutput.ExpiresIn">
|
||||
<summary>
|
||||
过期时间
|
||||
过期时间(秒)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatLoginOutput.UserInfo">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramLoginOutput.UserInfo">
|
||||
<summary>
|
||||
用户信息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Client.Dtos.WeChatRegisterInput">
|
||||
<member name="T:YD_Event.Application.Client.Dtos.MiniProgramRegisterInput">
|
||||
<summary>
|
||||
微信注册输入参数
|
||||
小程序注册输入参数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatRegisterInput.Openid">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramRegisterInput.Mobile">
|
||||
<summary>
|
||||
OpenId
|
||||
手机号(必填)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatRegisterInput.EncryptedData">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramRegisterInput.Password">
|
||||
<summary>
|
||||
加密数据
|
||||
密码(必填)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatRegisterInput.Iv">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramRegisterInput.VerificationCode">
|
||||
<summary>
|
||||
初始向量
|
||||
验证码(必填)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatRegisterInput.RawData">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramRegisterInput.NickName">
|
||||
<summary>
|
||||
原始数据
|
||||
昵称(可选)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatRegisterInput.Signature">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramRegisterInput.Avatar">
|
||||
<summary>
|
||||
签名
|
||||
头像(可选)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatRegisterInput.InviteCode">
|
||||
<member name="T:YD_Event.Application.Client.Dtos.MiniProgramRegisterOutput">
|
||||
<summary>
|
||||
邀请码 (可选)
|
||||
小程序注册输出参数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Client.Dtos.WeChatRegisterOutput">
|
||||
<summary>
|
||||
微信注册输出参数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatRegisterOutput.UserId">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramRegisterOutput.UserId">
|
||||
<summary>
|
||||
用户ID
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatRegisterOutput.Nickname">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramRegisterOutput.Mobile">
|
||||
<summary>
|
||||
手机号
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramRegisterOutput.NickName">
|
||||
<summary>
|
||||
昵称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatRegisterOutput.AvatarUrl">
|
||||
<summary>
|
||||
头像URL
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatRegisterOutput.RegisterTime">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramRegisterOutput.RegisterTime">
|
||||
<summary>
|
||||
注册时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Client.Dtos.WeChatResetPasswordInput">
|
||||
<member name="T:YD_Event.Application.Client.Dtos.MiniProgramResetPasswordInput">
|
||||
<summary>
|
||||
微信重置密码输入参数
|
||||
小程序重置密码输入参数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatResetPasswordInput.Openid">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramResetPasswordInput.Mobile">
|
||||
<summary>
|
||||
OpenId
|
||||
手机号(必填)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatResetPasswordInput.EncryptedData">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramResetPasswordInput.NewPassword">
|
||||
<summary>
|
||||
加密数据
|
||||
新密码(必填)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatResetPasswordInput.Iv">
|
||||
<member name="P:YD_Event.Application.Client.Dtos.MiniProgramResetPasswordInput.VerificationCode">
|
||||
<summary>
|
||||
初始向量
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatResetPasswordInput.Email">
|
||||
<summary>
|
||||
邮箱 (可选)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatResetPasswordInput.SmsCode">
|
||||
<summary>
|
||||
短信验证码 (可选)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Client.Dtos.WeChatResetPasswordOutput">
|
||||
<summary>
|
||||
微信重置密码输出参数
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatResetPasswordOutput.ResetToken">
|
||||
<summary>
|
||||
重置令牌
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatResetPasswordOutput.ExpireTime">
|
||||
<summary>
|
||||
过期时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatResetPasswordOutput.SendChannel">
|
||||
<summary>
|
||||
发送渠道 (email/sms)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Client.Dtos.WeChatUserInfo">
|
||||
<summary>
|
||||
微信用户信息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatUserInfo.OpenId">
|
||||
<summary>
|
||||
OpenId
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatUserInfo.NickName">
|
||||
<summary>
|
||||
昵称
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatUserInfo.Gender">
|
||||
<summary>
|
||||
性别
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatUserInfo.City">
|
||||
<summary>
|
||||
城市
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatUserInfo.Province">
|
||||
<summary>
|
||||
省份
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatUserInfo.Country">
|
||||
<summary>
|
||||
国家
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatUserInfo.AvatarUrl">
|
||||
<summary>
|
||||
头像URL
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatUserInfo.UnionId">
|
||||
<summary>
|
||||
UnionId
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.WeChatUserInfo.Watermark">
|
||||
<summary>
|
||||
水印
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Client.Dtos.Watermark">
|
||||
<summary>
|
||||
水印信息
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.Watermark.Timestamp">
|
||||
<summary>
|
||||
时间戳
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Application.Client.Dtos.Watermark.Appid">
|
||||
<summary>
|
||||
AppId
|
||||
验证码(必填)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Application.Client.Dtos.MyPageInput">
|
||||
@ -2719,33 +2604,28 @@
|
||||
微信小程序认证接口
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Client.OAuthController.Login(YD_Event.Application.Client.Dtos.WeChatLoginInput)">
|
||||
<member name="M:YD_Event.Application.Client.OAuthController.Login(YD_Event.Application.Client.Dtos.MiniProgramLoginInput)">
|
||||
<summary>
|
||||
登录接口
|
||||
</summary>
|
||||
<param name="input"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Client.OAuthController.Register(YD_Event.Application.Client.Dtos.WeChatRegisterInput)">
|
||||
<member name="M:YD_Event.Application.Client.OAuthController.Register(YD_Event.Application.Client.Dtos.MiniProgramRegisterInput)">
|
||||
<summary>
|
||||
注册接口
|
||||
</summary>
|
||||
<param name="input"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Client.OAuthController.ResetPassword(YD_Event.Application.Client.Dtos.WeChatResetPasswordInput)">
|
||||
<member name="M:YD_Event.Application.Client.OAuthController.ResetPassword(YD_Event.Application.Client.Dtos.MiniProgramResetPasswordInput)">
|
||||
<summary>
|
||||
找回密码接口
|
||||
重置密码接口
|
||||
</summary>
|
||||
<param name="input"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Client.OAuthController.DecryptWeChatData(System.String,System.String,System.String)">
|
||||
<summary>
|
||||
AES-128-CBC 解密
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:YD_Event.Application.Client.OAuthController.GenerateTokens(YD_Event.Core.Entities.AuthAccount)">
|
||||
<member name="M:YD_Event.Application.Client.OAuthController.GenerateTokens(YD_Event.Core.Entities.AppUser)">
|
||||
<summary>
|
||||
生成自定义 Token
|
||||
</summary>
|
||||
|
||||
@ -52,8 +52,8 @@ public class AppUser : Entity<long>, ISoftDelete, ICreatedUserId, ICreatedTime,
|
||||
/// <summary>
|
||||
/// 姓名
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 64)]
|
||||
public string Name { get; set; }
|
||||
[SugarColumn(Length = 64, IsNullable = true)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 性别
|
||||
@ -63,7 +63,8 @@ public class AppUser : Entity<long>, ISoftDelete, ICreatedUserId, ICreatedTime,
|
||||
/// <summary>
|
||||
/// 年龄
|
||||
/// </summary>
|
||||
public int Age { get; set; }
|
||||
[SugarColumn(IsNullable = true)]
|
||||
public int? Age { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 出生日期
|
||||
@ -75,18 +76,24 @@ public class AppUser : Entity<long>, ISoftDelete, ICreatedUserId, ICreatedTime,
|
||||
/// 联系电话
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 20)]
|
||||
public string Mobile { get; set; }
|
||||
public string Mobile { get; set; } = null!;
|
||||
|
||||
/// <summary>
|
||||
/// 密码(用于登录)
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 64, IsNullable = true)]
|
||||
public string? Password { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 身份证号码
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 20)]
|
||||
public string IdCardNumber { get; set; }
|
||||
[SugarColumn(Length = 20, IsNullable = true)]
|
||||
public string? IdCardNumber { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 身份证图片URL
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 512)]
|
||||
[SugarColumn(Length = 512, IsNullable = true)]
|
||||
public string? IdCardImageUrl { get; set; }
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -1,71 +0,0 @@
|
||||
using YD_Event.Core.Enum;
|
||||
|
||||
namespace YD_Event.Core.Entities;
|
||||
/// <summary>
|
||||
/// 博客授权用户
|
||||
/// </summary>
|
||||
public class AuthAccount : Entity<long>, ISoftDelete, ICreatedUserId, ICreatedTime, IUpdatedUserId, IUpdatedTime
|
||||
{
|
||||
/// <summary>
|
||||
/// 授权唯一标识
|
||||
/// </summary>
|
||||
public string OAuthId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 授权类型
|
||||
/// </summary>
|
||||
public string Type { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 博主标识
|
||||
/// </summary>
|
||||
public bool IsBlogger { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 姓名(昵称)
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 64)]
|
||||
public string? Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 性别
|
||||
/// </summary>
|
||||
public Gender Gender { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 头像
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 256)]
|
||||
public string? Avatar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 邮箱
|
||||
/// </summary>
|
||||
[SugarColumn(Length = 128)]
|
||||
public string? Email { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 标记删除
|
||||
/// </summary>
|
||||
public bool DeleteMark { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建人
|
||||
/// </summary>
|
||||
public long CreatedUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 创建时间
|
||||
/// </summary>
|
||||
public DateTime CreatedTime { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新人
|
||||
/// </summary>
|
||||
public long? UpdatedUserId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// 更新时间
|
||||
/// </summary>
|
||||
public DateTime? UpdatedTime { get; set; }
|
||||
}
|
||||
@ -509,6 +509,11 @@
|
||||
联系电话
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.AppUser.Password">
|
||||
<summary>
|
||||
密码(用于登录)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.AppUser.IdCardNumber">
|
||||
<summary>
|
||||
身份证号码
|
||||
@ -564,71 +569,6 @@
|
||||
更新时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Core.Entities.AuthAccount">
|
||||
<summary>
|
||||
博客授权用户
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.AuthAccount.OAuthId">
|
||||
<summary>
|
||||
授权唯一标识
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.AuthAccount.Type">
|
||||
<summary>
|
||||
授权类型
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.AuthAccount.IsBlogger">
|
||||
<summary>
|
||||
博主标识
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.AuthAccount.Name">
|
||||
<summary>
|
||||
姓名(昵称)
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.AuthAccount.Gender">
|
||||
<summary>
|
||||
性别
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.AuthAccount.Avatar">
|
||||
<summary>
|
||||
头像
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.AuthAccount.Email">
|
||||
<summary>
|
||||
邮箱
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.AuthAccount.DeleteMark">
|
||||
<summary>
|
||||
标记删除
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.AuthAccount.CreatedUserId">
|
||||
<summary>
|
||||
创建人
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.AuthAccount.CreatedTime">
|
||||
<summary>
|
||||
创建时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.AuthAccount.UpdatedUserId">
|
||||
<summary>
|
||||
更新人
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:YD_Event.Core.Entities.AuthAccount.UpdatedTime">
|
||||
<summary>
|
||||
更新时间
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:YD_Event.Core.Entities.Banner">
|
||||
<summary>
|
||||
轮播图配置
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user