提交代码

This commit is contained in:
zpc 2024-09-20 18:33:39 +08:00
parent 3badd0c692
commit 5b7a939dce
20 changed files with 738 additions and 27 deletions

View File

@ -16,6 +16,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="8.0.6" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.6" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Http" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="8.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="StackExchange.Redis" Version="2.8.0" />

View File

@ -0,0 +1,148 @@
using Newtonsoft.Json;
using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.DotNetCore.WeChat
{
/// <summary>
/// 小程序帮助类
/// </summary>
/// <param name="appId"></param>
/// <param name="secret"></param>
/// <param name="database"></param>
/// <param name="_httpClientFactory"></param>
public class MiniProgram(string appId, string secret, IDatabase database, IHttpClientFactory? _httpClientFactory)
{
public string AppId { get; set; } = appId;
string key = $"WeChat:{appId}";
// Method to get user's OpenID
public async Task<(string openId, string unionid, string session_key)> GetOpenid(string code)
{
string url = $"https://api.weixin.qq.com/sns/jscode2session?appid={appId}&secret={secret}&js_code={code}&grant_type=authorization_code";
var resUserInfo = await GetCurlData(url);
if (resUserInfo.ContainsKey("errcode"))
{
return (null, null, null);
}
string openid = resUserInfo.GetValueOrDefault("openid")?.ToString() ?? "";
string unionid = resUserInfo.GetValueOrDefault("unionid")?.ToString() ?? "";
string session_key = resUserInfo.GetValueOrDefault("session_key")?.ToString() ?? "";
return new(openid, unionid, session_key);
}
// Get user info based on access token and openid
public async Task<dynamic> GetUserInfoAsync(string openid)
{
var accessToken = await GetAccessToken();
string url = $"https://api.weixin.qq.com/sns/userinfo?access_token={accessToken}&openid={openid}&lang=zh_CN";
var response = await GetCurlData(url);
return response;
}
public async Task<string> GetAccessToken()
{
var accessTokenInfo = GetConfig();
if (accessTokenInfo != null)
{
return accessTokenInfo?.Access_token;
}
else
{
string url = $"https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={appId}&secret={secret}";
var resAccessToken = await GetCurlData(url);
if (resAccessToken.ContainsKey("errcode"))
{
throw new Exception("获取微信token失败");
}
string accessToken = resAccessToken["access_token"].ToString();
int expiresIn = Convert.ToInt32(resAccessToken["expires_in"]);
long accessTokenTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds() + expiresIn;
var data = new AccessToken(accessToken, accessTokenTime);
SetConfig(data);
return accessToken;
}
}
// Helper method for GET requests
private async Task<Dictionary<string, object>> GetCurlData(string url)
{
using HttpClient client = _httpClientFactory.CreateClient();
var response = await client.GetStringAsync(url);
return JsonConvert.DeserializeObject<Dictionary<string, object>>(response);
}
// Helper method for POST requests
private async Task<Dictionary<string, object>> PostCurlData(string url, object data)
{
using HttpClient client = _httpClientFactory.CreateClient();
var json = JsonConvert.SerializeObject(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
var result = await response.Content.ReadAsStringAsync();
return JsonConvert.DeserializeObject<Dictionary<string, object>>(result);
}
// Helper method for HTTP POST data
private async Task<string> HttpPostData(string url, object data)
{
using HttpClient client = _httpClientFactory.CreateClient();
var json = JsonConvert.SerializeObject(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(url, content);
return await response.Content.ReadAsStringAsync();
}
private AccessToken? GetConfig()
{
var json = database.StringGet(key);
if (!string.IsNullOrEmpty(json))
{
return JsonConvert.DeserializeObject<AccessToken>(json);
}
return null;
}
private void SetConfig(AccessToken access)
{
var outTime = new TimeSpan(0, 0, 7000);
database.StringSet(key, JsonConvert.SerializeObject(access), outTime);
}
}
/// <summary>
///
/// </summary>
public class AccessToken
{
public string? Access_token { get; }
public long Access_token_time { get; }
public AccessToken(string? access_token, long access_token_time)
{
Access_token = access_token;
Access_token_time = access_token_time;
}
public AccessToken()
{
}
}
}

View File

@ -0,0 +1,122 @@
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
using Newtonsoft.Json.Linq;
namespace HuanMeng.DotNetCore.WeChat
{
/// <summary>
///
/// </summary>
public class WXBizDataCrypt
{
private string appId;
private string sessionKey;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="appId">小程序的 appId</param>
/// <param name="sessionKey">用户在小程序登录后获取的会话密钥</param>
public WXBizDataCrypt(string appId, string sessionKey)
{
this.appId = appId;
this.sessionKey = sessionKey;
}
/// <summary>
/// 检验数据的真实性,并且获取解密后的明文
/// </summary>
/// <param name="encryptedData">加密的用户数据</param>
/// <param name="iv">与用户数据一同返回的初始向量</param>
/// <param name="data">解密后的原文</param>
/// <returns>成功0失败返回对应的错误码</returns>
public int DecryptData(string encryptedData, string iv, out string data)
{
data = null;
// 检查 sessionKey 长度
if (sessionKey.Length != 24)
{
return ErrorCode.IllegalAesKey;
}
// 检查 iv 长度
if (iv.Length != 24)
{
return ErrorCode.IllegalIv;
}
try
{
byte[] aesKey = Convert.FromBase64String(sessionKey);
byte[] aesIV = Convert.FromBase64String(iv);
byte[] aesCipher = Convert.FromBase64String(encryptedData);
using (Aes aesAlg = Aes.Create())
{
aesAlg.Key = aesKey;
aesAlg.IV = aesIV;
aesAlg.Mode = CipherMode.CBC;
aesAlg.Padding = PaddingMode.PKCS7;
using (ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV))
{
using (MemoryStream msDecrypt = new MemoryStream(aesCipher))
{
using (CryptoStream csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Read))
{
using (StreamReader srDecrypt = new StreamReader(csDecrypt))
{
// 解密后的明文
data = srDecrypt.ReadToEnd();
}
}
}
}
}
JObject dataObj = JObject.Parse(data);
// 检查 appId
if (dataObj["watermark"]["appid"].ToString() != this.appId)
{
return ErrorCode.IllegalBuffer;
}
return ErrorCode.OK;
}
catch
{
return ErrorCode.IllegalBuffer;
}
}
}
public static class ErrorCode
{
public const int OK = 0;
public const int IllegalAesKey = -41001;
public const int IllegalIv = -41002;
public const int IllegalBuffer = -41003;
}
public class WXBizDataCryptModel
{
/// <summary>
///
/// </summary>
public string EncryptedData;
/// <summary>
///
/// </summary>
public string Iv;
public int UserId { get; set; }
}
}

View File

@ -1,4 +1,5 @@
using HuanMeng.DotNetCore.MultiTenant;
using HuanMeng.MiaoYu.Code.Payment;
using System;
using System.Collections.Generic;
@ -38,6 +39,11 @@ namespace HuanMeng.MiaoYu.Code.AppExtend
/// 租户
/// </summary>
public Guid TenantId { get; set; }
/// <summary>
/// 项目支付数据
/// </summary>
public PaymentModel? Payment { get; set; }
}

View File

@ -1,12 +1,5 @@
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.MiaoYu.Code.AppExtend
{
/// <summary>

View File

@ -168,6 +168,11 @@ namespace HuanMeng.MiaoYu.Code.AppExtend
newAppConfig.ConnectionString = appConfig.ConnectionString;
newAppConfig.DomainName = appConfig.DomainName;
newAppConfig.RedisConnectionString = appConfig.RedisConnectionString;
if (appConfig.Payment == null)
{
appConfig.Payment = new PaymentModel() { };
}
newAppConfig.Payment = appConfig.Payment;
return newAppConfig;
}
/// <summary>

View File

@ -1,33 +1,18 @@
using AutoMapper;
using HuanMeng.DotNetCore.Base;
using HuanMeng.DotNetCore.JwtInfrastructure;
using HuanMeng.DotNetCore.JwtInfrastructure.Interface;
using HuanMeng.DotNetCore.MultiTenant;
using HuanMeng.DotNetCore.MultiTenant.Contract;
using HuanMeng.MiaoYu.Code.AppExtend;
using HuanMeng.MiaoYu.Code.Cache;
using HuanMeng.MiaoYu.Code.Cache.Contract;
using HuanMeng.MiaoYu.Code.DataAccess;
using HuanMeng.MiaoYu.Code.TencentUtile;
using HuanMeng.MiaoYu.Code.Users.UserAccount;
using HuanMeng.MiaoYu.Code.Users.UserAccount.Contract;
using HuanMeng.MiaoYu.Model.Dto;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.IdentityModel.Tokens;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using IDatabase = StackExchange.Redis.IDatabase;
namespace HuanMeng.MiaoYu.Code.Base
{
@ -416,4 +401,21 @@ namespace HuanMeng.MiaoYu.Code.Base
}
#endregion
}
public static class MiaoYuBaseExtend
{
/// <summary>
/// 微信小程序登录验证
/// </summary>
/// <param name="miaoYuBase"></param>
/// <returns></returns>
public static DotNetCore.WeChat.MiniProgram GetMiniProgram(this MiaoYuBase miaoYuBase)
{
return new DotNetCore.WeChat.MiniProgram(
miaoYuBase.AppConfig.Payment?.WeChatConfig?.AppId ?? "",
miaoYuBase.AppConfig.Payment?.WeChatConfig?.AppSecret ?? "",
miaoYuBase.RedisCache,
miaoYuBase.HttpClientFactory);
}
}
}

View File

@ -27,6 +27,7 @@
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="8.0.1" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="8.0.0" />
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.Api" Version="3.5.0" />
<PackageReference Include="SKIT.FlurlHttpClient.Wechat.TenpayV3" Version="3.7.0" />
<PackageReference Include="StackExchange.Redis" Version="2.8.0" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="7.6.2" />

View File

@ -13,6 +13,7 @@ using SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings;
using SKIT.FlurlHttpClient.Wechat.TenpayV3;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Utilities;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models;
using HuanMeng.MiaoYu.Code.Base;
@ -108,12 +109,30 @@ namespace HuanMeng.MiaoYu.Code.Payment
/// <returns></returns>
public static IPayment GetPayment(string payment, MiaoYuBase miaoYuBase)
{
//miaoYuBase.AppConfig.Payment
if (payment == "zfb")
{
return new AlipayPayment(AlipayConfig, miaoYuBase.TenantInfo, miaoYuBase._UserId);
}
return new WeChatPayment(wxClient, weChatConfig, miaoYuBase.TenantInfo, miaoYuBase._UserId);
if (miaoYuBase.AppConfig != null)
{
if (miaoYuBase.AppConfig.Payment == null)
{
miaoYuBase.AppConfig.Payment = new PaymentModel()
{
WeChatConfig = weChatConfig
};
}
if (miaoYuBase.AppConfig.Payment.WeChatConfig == null)
{
miaoYuBase.AppConfig.Payment.WeChatConfig = weChatConfig;
}
}
var _weChatConfig = miaoYuBase.AppConfig.Payment.WeChatConfig ?? weChatConfig;
var _wxClient = miaoYuBase.AppConfig.Payment.WxClient ?? wxClient;
return new WeChatPayment(_wxClient, _weChatConfig, miaoYuBase.TenantInfo, miaoYuBase._UserId);
}
/// <summary>

View File

@ -0,0 +1,66 @@
using Alipay.EasySDK.Kernel;
using HuanMeng.MiaoYu.Code.Payment.WeChat;
using SKIT.FlurlHttpClient.Wechat.TenpayV3;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Models;
using SKIT.FlurlHttpClient.Wechat.TenpayV3.Settings;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.MiaoYu.Code.Payment
{
/// <summary>
///
/// </summary>
public class PaymentModel
{
/// <summary>
/// 微信支付数据
/// </summary>
public WeChatConfig? WeChatConfig { get; set; }
/// <summary>
/// 支付宝支付数据
/// </summary>
public Config? AlipayConfig { get; set; }
/// <summary>
///
/// </summary>
private WechatTenpayClient _wxClient;
/// <summary>
/// 微信支付客户端
/// </summary>
public WechatTenpayClient? WxClient
{
get
{
if (_wxClient == null)
{
if (WeChatConfig == null)
{
return null;
}
var manager = new InMemoryCertificateManager();
/* 仅列出必须配置项。也包含一些诸如超时时间、UserAgent 等的配置项 */
var wechatTenpayClientOptions = new WechatTenpayClientOptions()
{
MerchantId = WeChatConfig.MchId,
MerchantV3Secret = WeChatConfig.Key,
MerchantCertificateSerialNumber = WeChatConfig.MerchantCertificateSerialNumber,
MerchantCertificatePrivateKey = WeChatConfig.MerchantCertificatePrivateKey,
PlatformCertificateManager = manager
};
_wxClient = new WechatTenpayClient(wechatTenpayClientOptions);
}
return _wxClient;
}
}
}
}

View File

@ -9,7 +9,7 @@ using System.Threading.Tasks;
namespace HuanMeng.MiaoYu.Code.Users.UserAccount.PhoneAccount
{
/// <summary>
/// 登录参数
/// 登录参数
/// </summary>
public class PhoneLoginParams : BaseLoginParams
{

View File

@ -0,0 +1,104 @@
using HuanMeng.MiaoYu.Code.Users.UserAccount.Contract;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using HuanMeng.DotNetCore.WeChat;
using HuanMeng.MiaoYu.Code.Users.UserAccount.PhoneAccount;
namespace HuanMeng.MiaoYu.Code.Users.UserAccount.WeChat
{
/// <summary>
/// PhoneLoginParams
/// </summary>
public class MiniProgramAccountLogin(MiniProgram miniProgram, DAO dao) : IUserAccount
{
public override async Task<LoginAccountInfo> LoginAsync(BaseLoginParams loginParams)
{
var login = loginParams as MiniProgramAccountParams;
if (login == null)
{
throw new ArgumentNullException("登录方式错误");
}
if (string.IsNullOrEmpty(login.Code))
{
throw new ArgumentNullException("小程序code不能为空");
}
(string openId, string unionid, string session_key) = await miniProgram.GetOpenid(login.Code);
if (openId == null)
{
throw new ArgumentNullException("小程序登录失败");
}
var account = dao.daoDbMiaoYu.context.T_User_MiniProgram_Account.FirstOrDefault(it => it.OpenId == openId); T_User? user = null;
if (account == null)
{
user = new T_User()
{
UpdatedAt = DateTime.Now,
CreatedAt = DateTime.Now,
IsActive = true,
LastLoginAt = DateTime.Now,
LastLoginTypeAt = 2,
Email = "",
NickName = "微信用户",
PhoneNum = "",
RegisterType = 2,
TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId,
UserName = "微信用户",
State = 0,
};
dao.daoDbMiaoYu.context.T_User.Add(user);
dao.daoDbMiaoYu.context.SaveChanges();
account = new T_User_MiniProgram_Account()
{
CreateAt = DateTime.Now,
OpenId = openId,
SessionKey = session_key,
Unionid = unionid,
UpdateAt = DateTime.Now,
UserId = user.Id,
};
dao.daoDbMiaoYu.context.Add(account);
dao.daoDbMiaoYu.context.SaveChanges();
}
else
{
user = await dao.daoDbMiaoYu.context.T_User.FirstOrDefaultAsync(it => it.Id == account.UserId);
}
//WXBizDataCrypt wXBizDataCrypt = new WXBizDataCrypt(miniProgram.AppId, session_key);
account.UpdateAt = DateTime.Now;
account.SessionKey = session_key;
if (user == null)
{
user = new T_User()
{
UpdatedAt = DateTime.Now,
CreatedAt = DateTime.Now,
IsActive = true,
LastLoginAt = DateTime.Now,
LastLoginTypeAt = 2,
Email = "",
NickName = "微信用户",
PhoneNum = "",
RegisterType = 2,
TenantId = dao.daoDbMiaoYu.context.TenantInfo.TenantId,
UserName = "微信用户",
State = 0,
};
dao.daoDbMiaoYu.context.T_User.Add(user);
}
dao.daoDbMiaoYu.context.SaveChanges();
return new LoginAccountInfo()
{
NickName = user.NickName,
UserId = user.Id,
};
}
}
}

View File

@ -0,0 +1,22 @@
using HuanMeng.MiaoYu.Code.Users.UserAccount.Contract;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.MiaoYu.Code.Users.UserAccount.WeChat
{
/// <summary>
///
/// </summary>
public class MiniProgramAccountParams : BaseLoginParams
{
/// <summary>
/// 微信小程序code
/// </summary>
public string Code { get; set; }
}
}

View File

@ -1,9 +1,11 @@
using HuanMeng.DotNetCore.Base;
using HuanMeng.DotNetCore.WeChat;
using HuanMeng.MiaoYu.Code.Base;
using HuanMeng.MiaoYu.Code.DataAccess;
using HuanMeng.MiaoYu.Code.Users.UserAccount;
using HuanMeng.MiaoYu.Code.Users.UserAccount.Contract;
using HuanMeng.MiaoYu.Code.Users.UserAccount.PhoneAccount;
using HuanMeng.MiaoYu.Code.Users.UserAccount.WeChat;
using HuanMeng.MiaoYu.Model.Dto;
using HuanMeng.MiaoYu.Model.Dto.Account;
using HuanMeng.MiaoYu.Model.Dto.Character;
@ -18,6 +20,7 @@ using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
using System.Linq;
using System.Security.Claims;
using System.Text;
@ -82,6 +85,14 @@ namespace HuanMeng.MiaoYu.Code.Users
Ip = ip
};
}
else if (requestLoginModel.LoginType == 2)
{//
userAccount = new MiniProgramAccountLogin(this.GetMiniProgram(), Dao);
loginParams = new MiniProgramAccountParams()
{
Code = requestLoginModel.Code,
};
}
else
{
throw new Exception("不支持的登录方式");
@ -163,6 +174,66 @@ namespace HuanMeng.MiaoYu.Code.Users
});
}
/// <summary>
///
/// </summary>
/// <param name="wXBizDataCryptModel"></param>
/// <returns></returns>
public async Task<string> GetMiniProgramUserInfo(WXBizDataCryptModel wXBizDataCryptModel)
{
var appId = this.AppConfig.Payment?.WeChatConfig?.AppId ?? "";
var account = Dao.daoDbMiaoYu.context.T_User_MiniProgram_Account.FirstOrDefault(it => it.UserId == wXBizDataCryptModel.UserId);
WXBizDataCrypt wXBizDataCrypt = new WXBizDataCrypt(appId, account.SessionKey ?? "");
var t = wXBizDataCrypt.DecryptData(wXBizDataCryptModel.EncryptedData, wXBizDataCryptModel.Iv, out var data);
if (t == 0)
{
var jsonData = JsonConvert.DeserializeObject<JObject>(data);
if (jsonData?["nickName"] != null)
{
string nickName = jsonData?["nickName"]?.ToString();
}
}
return data;
}
/// <summary>
/// 修改用户昵称
/// </summary>
/// <param name="nickName"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public async Task<BaseResponse<bool>> UpdateUserNickName(string nickName)
{
var user = Dao.daoDbMiaoYu.context.T_User.FirstOrDefault(it => it.Id == _UserId);
if (user == null)
{
throw new Exception("用户不存在");
}
user.NickName = nickName;
await Dao.daoDbMiaoYu.context.SaveChangesAsync();
string sqlString = $@"update M_Songs set AuthorName='{nickName}' where AuthorId={_UserId}";
await Dao.daoDbMiaoYu.context.Database.ExecuteSqlRawAsync(sqlString);
return new BaseResponse<bool>(ResonseCode.Success, "", true);
}
/// <summary>
/// 修改用户头像
/// </summary>
/// <param name="userIcon"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
public async Task<BaseResponse<bool>> UpdateUserIcon(string userIcon)
{
var user = Dao.daoDbMiaoYu.context.T_User.FirstOrDefault(it => it.Id == _UserId);
if (user == null)
{
throw new Exception("用户不存在");
}
user.UserIconUrl = userIcon;
await Dao.daoDbMiaoYu.context.SaveChangesAsync();
return new BaseResponse<bool>(ResonseCode.Success, "", true);
}
/// <summary>
/// 交易记录
/// </summary>
@ -191,6 +262,7 @@ namespace HuanMeng.MiaoYu.Code.Users
}
return new BaseResponse<List<TransactionDto>>(ResonseCode.Success, "", list);
}
/// <summary>
/// 获取未使用的记忆卡列表
/// </summary>

View File

@ -213,6 +213,11 @@ public partial class MiaoYuContext : MultiTenantDbContext//DbContext
/// </summary>
public virtual DbSet<T_User_MemoryCard> T_User_MemoryCard { get; set; }
/// <summary>
/// 小程序登录表
/// </summary>
public virtual DbSet<T_User_MiniProgram_Account> T_User_MiniProgram_Account { get; set; }
/// <summary>
/// 手机号登录表
/// </summary>
@ -1291,6 +1296,35 @@ public partial class MiaoYuContext : MultiTenantDbContext//DbContext
}
});
modelBuilder.Entity<T_User_MiniProgram_Account>(entity =>
{
entity.HasKey(e => e.Id).HasName("PK__T_User_M__3214EC073889A8B9");
entity.ToTable(tb => tb.HasComment("小程序登录表"));
entity.Property(e => e.Id).HasComment("主键");
entity.Property(e => e.CreateAt)
.HasComment("创建时间")
.HasColumnType("datetime");
entity.Property(e => e.OpenId)
.HasMaxLength(200)
.HasComment("用户唯一标识");
entity.Property(e => e.SessionKey).HasMaxLength(200);
entity.Property(e => e.TenantId).HasComment("租户");
entity.Property(e => e.Unionid)
.HasMaxLength(200)
.HasComment("用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台账号下会返回,详见");
entity.Property(e => e.UpdateAt)
.HasComment("修改时间")
.HasColumnType("datetime");
entity.Property(e => e.UserId).HasComment("用户Id");
//添加全局筛选器
if (this.TenantInfo != null)
{
entity.HasQueryFilter(it => it.TenantId == this.TenantInfo.TenantId);
}
});
modelBuilder.Entity<T_User_Phone_Account>(entity =>
{
entity.HasKey(e => e.Id).HasName("PK__T_User_P__3214EC07987BDDB2");

View File

@ -1,4 +1,4 @@
using System;
using System;
namespace HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;

View File

@ -0,0 +1,43 @@
using System;
namespace HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
/// <summary>
/// 小程序登录表
/// </summary>
public partial class T_User_MiniProgram_Account: MultiTenantEntity
{
/// <summary>
/// 主键
/// </summary>
public virtual int Id { get; set; }
public override Guid TenantId { get; set; }
/// <summary>
/// 用户Id
/// </summary>
public virtual int UserId { get; set; }
/// <summary>
/// 用户唯一标识
/// </summary>
public virtual string OpenId { get; set; } = null!;
/// <summary>
/// 用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台账号下会返回,详见
/// </summary>
public virtual string? Unionid { get; set; }
public virtual string? SessionKey { get; set; }
/// <summary>
/// 创建时间
/// </summary>
public virtual DateTime CreateAt { get; set; }
/// <summary>
/// 修改时间
/// </summary>
public virtual DateTime UpdateAt { get; set; }
}

View File

@ -0,0 +1,30 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace HuanMeng.MiaoYu.Model.Dto.Account
{
/// <summary>
///
/// </summary>
public class RequestAccountCommonUser
{
/// <summary>
///
/// </summary>
public string NickName { get; set; }
}
/// <summary>
///
/// </summary>
public class RequestAccountCommonUserImage
{
/// <summary>
///
/// </summary>
public string UserIcon { get; set; }
}
}

View File

@ -17,7 +17,7 @@ namespace HuanMeng.MiaoYu.Model.Dto.Account
public string? VerificationCode { get; set; }
/// <summary>
/// 登录类型0token登录 1手机号2邮箱
/// 登录类型0token登录 1手机号2微信登录
/// </summary>
public int LoginType { get; set; }
@ -25,5 +25,10 @@ namespace HuanMeng.MiaoYu.Model.Dto.Account
/// token登录
/// </summary>
public string? Token { get; set; }
/// <summary>
/// 微信小程序登录Code
/// </summary>
public string? Code { get; set; }
}
}

View File

@ -2,6 +2,7 @@ using Azure;
using HuanMeng.DotNetCore.Base;
using HuanMeng.DotNetCore.Utility;
using HuanMeng.DotNetCore.WeChat;
using HuanMeng.MiaoYu.Code.Mall;
using HuanMeng.MiaoYu.Code.Other;
using HuanMeng.MiaoYu.Code.Users;
@ -76,6 +77,18 @@ namespace HuanMeng.MiaoYu.WebApi.Controllers
UserBLL userBLL = new UserBLL(ServiceProvider);
return await userBLL.GetUserInfo();
}
/// <summary>
/// 解析微信用户数据
/// </summary>
/// <returns></returns>
[AllowAnonymous]
[HttpPost]
public async Task<string> GetMiniProgramUserInfo([FromBody] WXBizDataCryptModel wXBizDataCryptModel)
{
UserBLL userBLL = new UserBLL(ServiceProvider);
return await userBLL.GetMiniProgramUserInfo(wXBizDataCryptModel);
}
/// <summary>
/// 我的账户
@ -98,7 +111,32 @@ namespace HuanMeng.MiaoYu.WebApi.Controllers
{
UserBLL userBLL = new UserBLL(ServiceProvider);
return await userBLL.GetTransactionRecords();
}
/// <summary>
/// 修改用户昵称
/// </summary>
/// <param name="requestAccountCommonUser"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
[HttpPost]
public async Task<BaseResponse<bool>> UpdateUserNickName([FromBody] RequestAccountCommonUser requestAccountCommonUser)
{
UserBLL userBLL = new UserBLL(ServiceProvider);
return await userBLL.UpdateUserNickName(requestAccountCommonUser.NickName);
}
/// <summary>
/// 修改用户头像
/// </summary>
/// <param name="requestAccountCommonUserImage"></param>
/// <returns></returns>
/// <exception cref="Exception"></exception>
[HttpPost]
public async Task<BaseResponse<bool>> UpdateUserIcon([FromBody] RequestAccountCommonUserImage requestAccountCommonUserImage)
{
UserBLL userBLL = new UserBLL(ServiceProvider);
return await userBLL.UpdateUserIcon(requestAccountCommonUserImage.UserIcon);
}