提交代码
This commit is contained in:
parent
3badd0c692
commit
5b7a939dce
|
|
@ -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" />
|
||||
|
|
|
|||
148
src/0-core/HuanMeng.DotNetCore/WeChat/MiniProgram.cs
Normal file
148
src/0-core/HuanMeng.DotNetCore/WeChat/MiniProgram.cs
Normal 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()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
122
src/0-core/HuanMeng.DotNetCore/WeChat/WXBizDataCrypt.cs
Normal file
122
src/0-core/HuanMeng.DotNetCore/WeChat/WXBizDataCrypt.cs
Normal 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; }
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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" />
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
66
src/0-core/HuanMeng.MiaoYu.Code/Payment/PaymentModel.cs
Normal file
66
src/0-core/HuanMeng.MiaoYu.Code/Payment/PaymentModel.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -9,7 +9,7 @@ using System.Threading.Tasks;
|
|||
namespace HuanMeng.MiaoYu.Code.Users.UserAccount.PhoneAccount
|
||||
{
|
||||
/// <summary>
|
||||
/// 登录参数
|
||||
/// 登录参数
|
||||
/// </summary>
|
||||
public class PhoneLoginParams : BaseLoginParams
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
|
||||
namespace HuanMeng.MiaoYu.Model.DbSqlServer.Db_MiaoYu;
|
||||
|
||||
|
|
|
|||
|
|
@ -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; }
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
@ -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; }
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user