From aba815f80522b2fd32cf96290328b712457f2687 Mon Sep 17 00:00:00 2001
From: wxd <123@qq.com>
Date: Wed, 14 May 2025 18:23:53 +0800
Subject: [PATCH] =?UTF-8?q?=E4=B8=89=E6=96=B9=E7=94=A8=E6=88=B7?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../BindThirdUserInAbpUserInputDto.cs | 19 ++
.../ThirdUsers/GetTokenReturn.cs | 13 ++
.../ThirdUsers/SignInResultDto.cs | 15 ++
.../ThirdUsers/ThirdLoginDto.cs | 6 +
.../ThirdUsers/ThirdUserDto.cs | 38 ++++
.../ThirdUsers/ThirdUserInputDto.cs | 36 +++
.../ThirdUsers/WeChatUserLoginInputDto.cs | 17 ++
.../ThirdUsers/ThirdUserAppService.cs | 212 ++++++++++++++++--
.../Enums/CacheKeys.cs | 13 ++
.../Controllers/MiniProgramTokenController.cs | 117 +++++++---
10 files changed, 439 insertions(+), 47 deletions(-)
create mode 100644 src/Shentun.Peis.Application.Contracts/ThirdUsers/BindThirdUserInAbpUserInputDto.cs
create mode 100644 src/Shentun.Peis.Application.Contracts/ThirdUsers/GetTokenReturn.cs
create mode 100644 src/Shentun.Peis.Application.Contracts/ThirdUsers/SignInResultDto.cs
create mode 100644 src/Shentun.Peis.Application.Contracts/ThirdUsers/ThirdUserDto.cs
create mode 100644 src/Shentun.Peis.Application.Contracts/ThirdUsers/ThirdUserInputDto.cs
create mode 100644 src/Shentun.Peis.Application.Contracts/ThirdUsers/WeChatUserLoginInputDto.cs
create mode 100644 src/Shentun.Peis.Domain.Shared/Enums/CacheKeys.cs
diff --git a/src/Shentun.Peis.Application.Contracts/ThirdUsers/BindThirdUserInAbpUserInputDto.cs b/src/Shentun.Peis.Application.Contracts/ThirdUsers/BindThirdUserInAbpUserInputDto.cs
new file mode 100644
index 0000000..041e99c
--- /dev/null
+++ b/src/Shentun.Peis.Application.Contracts/ThirdUsers/BindThirdUserInAbpUserInputDto.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Shentun.Peis.ThirdUsers
+{
+ public class BindThirdUserInAbpUserInputDto
+ {
+ ///
+ /// 第三方系统用户Id
+ ///
+ public Guid ThirdUserId { get; set; }
+
+ ///
+ /// 系统用户Id
+ ///
+ public Guid AbpUserId { get; set; }
+ }
+}
diff --git a/src/Shentun.Peis.Application.Contracts/ThirdUsers/GetTokenReturn.cs b/src/Shentun.Peis.Application.Contracts/ThirdUsers/GetTokenReturn.cs
new file mode 100644
index 0000000..81cb837
--- /dev/null
+++ b/src/Shentun.Peis.Application.Contracts/ThirdUsers/GetTokenReturn.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Shentun.Peis.ThirdUsers
+{
+ public class GetTokenReturn
+ {
+ public int code { get; set; }
+ public string message { get; set; }
+ public object data { get; set; }
+ }
+}
diff --git a/src/Shentun.Peis.Application.Contracts/ThirdUsers/SignInResultDto.cs b/src/Shentun.Peis.Application.Contracts/ThirdUsers/SignInResultDto.cs
new file mode 100644
index 0000000..dc8d998
--- /dev/null
+++ b/src/Shentun.Peis.Application.Contracts/ThirdUsers/SignInResultDto.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Shentun.Peis.ThirdUsers
+{
+ public class SignInResultDto
+ {
+ public string access_token { get; set; }
+ public string refresh_token { get; set; }
+ public string token_type { get; set; }
+ public int expires_in { get; set; }
+
+ }
+}
diff --git a/src/Shentun.Peis.Application.Contracts/ThirdUsers/ThirdLoginDto.cs b/src/Shentun.Peis.Application.Contracts/ThirdUsers/ThirdLoginDto.cs
index 00e3f43..04c4d67 100644
--- a/src/Shentun.Peis.Application.Contracts/ThirdUsers/ThirdLoginDto.cs
+++ b/src/Shentun.Peis.Application.Contracts/ThirdUsers/ThirdLoginDto.cs
@@ -10,6 +10,12 @@ namespace Shentun.Peis.ThirdUsers
/// 是否有token
///
public string IsToken { get; set; } = "Y";
+
+ ///
+ /// 提示
+ ///
+ public string Message { get; set; }
+
///
/// 微信OpenId
///
diff --git a/src/Shentun.Peis.Application.Contracts/ThirdUsers/ThirdUserDto.cs b/src/Shentun.Peis.Application.Contracts/ThirdUsers/ThirdUserDto.cs
new file mode 100644
index 0000000..aa17ba9
--- /dev/null
+++ b/src/Shentun.Peis.Application.Contracts/ThirdUsers/ThirdUserDto.cs
@@ -0,0 +1,38 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Text;
+
+namespace Shentun.Peis.ThirdUsers
+{
+ public class ThirdUserDto : AuditedEntityDtoName
+ {
+ ///
+ /// 手机号码
+ ///
+ public string MobilePhone { get; set; }
+
+ ///
+ /// abp用户表Id
+ ///
+ public Guid? AbpUserId { get; set; }
+
+
+ ///
+ /// 是否启用
+ ///
+ public char IsActive { get; set; }
+
+
+ ///
+ /// 微信openid
+ ///
+ public string? WechatOpenId { get; set; }
+
+ ///
+ /// 用户注册方式(0.小程序注册 1.后台添加) 默认0
+ ///
+ public char UserRegisterFlag { get; set; }
+
+ }
+}
diff --git a/src/Shentun.Peis.Application.Contracts/ThirdUsers/ThirdUserInputDto.cs b/src/Shentun.Peis.Application.Contracts/ThirdUsers/ThirdUserInputDto.cs
new file mode 100644
index 0000000..15b9036
--- /dev/null
+++ b/src/Shentun.Peis.Application.Contracts/ThirdUsers/ThirdUserInputDto.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Shentun.Peis.ThirdUsers
+{
+ public class ThirdUserInputDto
+ {
+ ///
+ /// 手机号码
+ ///
+ public string MobilePhone { get; set; }
+
+ ///
+ /// abp用户表Id
+ ///
+ public Guid? AbpUserId { get; set; }
+
+
+ ///
+ /// 是否启用
+ ///
+ public char? IsActive { get; set; }
+
+
+ ///
+ /// 微信openid
+ ///
+ public string WechatOpenId { get; set; }
+
+ ///
+ /// 用户注册方式(0.小程序注册 1.后台添加) 默认0
+ ///
+ public char? UserRegisterFlag { get; set; }
+ }
+}
diff --git a/src/Shentun.Peis.Application.Contracts/ThirdUsers/WeChatUserLoginInputDto.cs b/src/Shentun.Peis.Application.Contracts/ThirdUsers/WeChatUserLoginInputDto.cs
new file mode 100644
index 0000000..d274f40
--- /dev/null
+++ b/src/Shentun.Peis.Application.Contracts/ThirdUsers/WeChatUserLoginInputDto.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel.DataAnnotations.Schema;
+using System.Text;
+
+namespace Shentun.Peis.ThirdUsers
+{
+ public class WeChatUserLoginInputDto
+ {
+ public string JsCode { get; set; }
+
+ ///
+ /// 手机号码
+ ///
+ public string MobilePhone { get; set; }
+ }
+}
diff --git a/src/Shentun.Peis.Application/ThirdUsers/ThirdUserAppService.cs b/src/Shentun.Peis.Application/ThirdUsers/ThirdUserAppService.cs
index 887ecbd..272c54e 100644
--- a/src/Shentun.Peis.Application/ThirdUsers/ThirdUserAppService.cs
+++ b/src/Shentun.Peis.Application/ThirdUsers/ThirdUserAppService.cs
@@ -1,39 +1,215 @@
using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.Extensions.Caching.Distributed;
+using Microsoft.Extensions.Configuration;
using OpenIddict.Abstractions;
+using Shentun.Peis.Enums;
+using Shentun.Peis.Models;
+using Shentun.Peis.SysParmValues;
+using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
+using System.Net.Http;
+using System.Net.Http.Headers;
using System.Security.Claims;
using System.Text;
+using System.Text.Json;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Services;
+using Volo.Abp.Caching;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
namespace Shentun.Peis.ThirdUsers
{
+ ///
+ /// 第三方用户
+ ///
+ [ApiExplorerSettings(GroupName = "Work")]
+ [Authorize]
public class ThirdUserAppService : ApplicationService
{
- //private readonly IOpenIddictScopeManager _scopeManager;
- //private readonly SignInManager _signInManager;
- //private readonly IRepository _identityUserRepository;
- //private readonly IdentityUserManager _identityUserManager;
-
- //public ThirdUserAppService(
- // IOpenIddictScopeManager scopeManager,
- // SignInManager signInManager,
- // IRepository identityUserRepository,
- // IdentityUserManager identityUserManager)
- //{
- // _scopeManager = scopeManager;
- // _signInManager = signInManager;
- // _identityUserRepository = identityUserRepository;
- // _identityUserManager = identityUserManager;
- //}
-
-
+
+
+ private readonly IConfiguration _configuration;
+ private readonly IDistributedCache _cache;
+ private readonly IRepository _thirdUserRepository;
+ private readonly CacheService _cacheService;
+ private readonly IRepository _identityUserRepository;
+ public ThirdUserAppService(
+ IConfiguration configuration,
+ IDistributedCache cache,
+ IRepository thirdUserRepository,
+ CacheService cacheService,
+ IRepository identityUserRepository)
+ {
+ _configuration = configuration;
+ _cache = cache;
+ _thirdUserRepository = thirdUserRepository;
+ _cacheService = cacheService;
+ _identityUserRepository = identityUserRepository;
+ }
+
+ ///
+ /// 微信用户登录
+ ///
+ ///
+ ///
+ [AllowAnonymous]
+ [HttpPost("api/app/ThirdUser/WeChatUserLogin")]
+ public async Task WeChatUserLoginAsync(WeChatUserLoginInputDto input)
+ {
+ var dic = new Dictionary
+ {
+ {"jsCode",input.JsCode},
+ {"client_id","Peis_MiniProgram"},
+ {"mobile_phone",input.MobilePhone},
+ {"grant_type","mini_program"},
+ {"scope","Peis"}
+ };
+ //
+ var dicStr = dic.Select(m => m.Key + "=" + m.Value).DefaultIfEmpty().Aggregate((m, n) => m + "&" + n);
+ var token = await GetTokenAsync(dicStr);
+ var options = new DistributedCacheEntryOptions()
+ .SetAbsoluteExpiration(TimeSpan.FromDays(3));
+ var sessionKey = CacheKeys.SessionKey + Guid.NewGuid().ToString();
+ var sessionKeyValue = Guid.NewGuid().ToString();
+ _cache.Set(sessionKey, sessionKeyValue, options);
+ token.SessionKey = sessionKey;
+ token.SessionKeyValue = sessionKeyValue;
+
+ return token;
+
+ }
+
+
+
+ ///
+ /// 获取第三方用户信息
+ ///
+ ///
+ [HttpPost("api/app/ThirdUser/GetList")]
+ public async Task> GetListAsync(ThirdUserInputDto input)
+ {
+ var query = await _thirdUserRepository.GetQueryableAsync();
+ if (input.AbpUserId != null)
+ {
+ query = query.Where(m => m.AbpUserId == input.AbpUserId);
+ }
+ if (input.UserRegisterFlag != null)
+ {
+ query = query.Where(m => m.UserRegisterFlag == input.UserRegisterFlag);
+ }
+ if (input.IsActive != null)
+ {
+ query = query.Where(m => m.IsActive == input.IsActive);
+ }
+ if (!string.IsNullOrWhiteSpace(input.MobilePhone))
+ {
+ query = query.Where(m => m.MobilePhone == input.MobilePhone);
+ }
+ if (!string.IsNullOrWhiteSpace(input.WechatOpenId))
+ {
+ query = query.Where(m => m.WechatOpenId == input.WechatOpenId);
+ }
+
+ var entListDto = query.OrderByDescending(o => o.CreationTime).ToList().Select(s => new ThirdUserDto
+ {
+ AbpUserId = s.AbpUserId,
+ CreationTime = s.CreationTime,
+ CreatorId = s.CreatorId,
+ CreatorName = _cacheService.GetSurnameAsync(s.CreatorId).GetAwaiter().GetResult(),
+ Id = s.Id,
+ IsActive = s.IsActive,
+ LastModificationTime = s.LastModificationTime,
+ LastModifierId = s.LastModifierId,
+ LastModifierName = _cacheService.GetSurnameAsync(s.LastModifierId).GetAwaiter().GetResult(),
+ MobilePhone = s.MobilePhone,
+ UserRegisterFlag = s.UserRegisterFlag,
+ WechatOpenId = s.WechatOpenId
+ }).ToList();
+
+ return entListDto;
+ }
+
+ ///
+ /// 绑定第三方用户归属到系统用户
+ ///
+ ///
+ [HttpPost("api/app/ThirdUser/BindThirdUserInAbpUser")]
+ public async Task BindThirdUserInAbpUserAsync(BindThirdUserInAbpUserInputDto input)
+ {
+ var identityUser = await _identityUserRepository.FirstOrDefaultAsync(f => f.Id == input.AbpUserId);
+ if (identityUser == null)
+ {
+ throw new UserFriendlyException("系统用户不存在");
+ }
+
+ var thirdUser = await _thirdUserRepository.FirstOrDefaultAsync(f => f.Id == input.ThirdUserId);
+ if (thirdUser == null)
+ {
+ throw new UserFriendlyException("第三方用户不存在");
+ }
+
+ thirdUser.AbpUserId = input.AbpUserId;
+
+ await _thirdUserRepository.UpdateAsync(thirdUser);
+
+ }
+
+
+ private async Task GetTokenAsync(string request)
+ {
+ using var client = new HttpClient();
+ HttpContent httpContent = new StringContent(request);
+ httpContent.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
+ var url = _configuration.GetSection("AuthServer").
+ GetSection("Authority").Value + "/connect/token";
+ var tokenResult = await client.PostAsync(url
+ , httpContent);
+ var tokenResultStr = await tokenResult.Content.ReadAsStringAsync();
+ if (tokenResult.IsSuccessStatusCode)
+ {
+ var thirdLoginDto = new ThirdLoginDto();
+
+ if (!string.IsNullOrEmpty(tokenResultStr))
+ {
+
+ if (tokenResultStr.ToLower().Contains("openid"))
+ {
+ thirdLoginDto = JsonSerializer.Deserialize(tokenResultStr,
+ new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
+ }
+ else
+ {
+ var signResult = JsonSerializer.Deserialize(tokenResultStr,
+ new JsonSerializerOptions() { PropertyNameCaseInsensitive = true });
+ thirdLoginDto = new ThirdLoginDto
+ {
+ IsToken = "Y",
+ ExpiresIn = signResult.expires_in,
+ AccessToken = signResult.access_token,
+ RefreshToken = signResult.refresh_token
+ };
+ }
+
+ return thirdLoginDto;
+ }
+ else
+ {
+ throw new UserFriendlyException("token值为空");
+ }
+
+ }
+ else
+ {
+ throw new UserFriendlyException("获取token失败:" + tokenResultStr);
+ }
+ }
}
}
diff --git a/src/Shentun.Peis.Domain.Shared/Enums/CacheKeys.cs b/src/Shentun.Peis.Domain.Shared/Enums/CacheKeys.cs
new file mode 100644
index 0000000..0192265
--- /dev/null
+++ b/src/Shentun.Peis.Domain.Shared/Enums/CacheKeys.cs
@@ -0,0 +1,13 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace Shentun.Peis.Enums
+{
+ public class CacheKeys
+ {
+ public const string OpenIdKey = "OpenIdKey";
+ public const string SmsKey = "SmsKey";
+ public const string SessionKey = "SessionKey";
+ }
+}
diff --git a/src/Shentun.Peis.HttpApi.Host/Controllers/MiniProgramTokenController.cs b/src/Shentun.Peis.HttpApi.Host/Controllers/MiniProgramTokenController.cs
index b57b547..40b61a2 100644
--- a/src/Shentun.Peis.HttpApi.Host/Controllers/MiniProgramTokenController.cs
+++ b/src/Shentun.Peis.HttpApi.Host/Controllers/MiniProgramTokenController.cs
@@ -1,4 +1,5 @@
-using Microsoft.AspNetCore.Identity;
+using Hangfire.States;
+using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using OpenIddict.Abstractions;
@@ -11,6 +12,7 @@ using Volo.Abp;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.Identity;
using Volo.Abp.OpenIddict.Controllers;
+using Volo.Abp.Uow;
namespace Shentun.Peis.Controllers
{
@@ -51,23 +53,79 @@ namespace Shentun.Peis.Controllers
if (grantType == "mini_program")
{
+ var resultDto = new ThirdLoginDto();
+
+
//小程序登录
// 获取小程序 code 并换取 openid
var jsCode = request.GetParameter("jsCode").ToString();
+ var mobilePhone = request.GetParameter("mobile_phone").ToString();
var wechatSession = await WeChatHelper.GetWechatSession(_configuration, jsCode);
- var thirdUserEnt = await _thirdUserRepository.FirstOrDefaultAsync(f => f.WechatOpenId == wechatSession.OpenId && f.IsActive == 'Y' && f.AbpUserId != null);
+ var thirdUserEnt = await _thirdUserRepository.FirstOrDefaultAsync(f => f.WechatOpenId == wechatSession.OpenId);
+
if (thirdUserEnt == null)
{
- throw new UserFriendlyException("用户未授权");
+ //未注册 注册信息
+ thirdUserEnt = new ThirdUser
+ {
+ AbpUserId = null,
+ IsActive = 'Y',
+ MobilePhone = mobilePhone,
+ UserRegisterFlag = '0',
+ WechatOpenId = wechatSession.OpenId
+ };
+
+ await _thirdUserRepository.InsertAsync(thirdUserEnt, true);
+
+ resultDto = new ThirdLoginDto
+ {
+ IsToken = "N",
+ Message = "用户未授权",
+ OpenId = wechatSession.OpenId
+ };
+
+ return Ok(resultDto);
+
+ }
+ else if (thirdUserEnt.IsActive == 'N')
+ {
+ resultDto = new ThirdLoginDto
+ {
+ IsToken = "N",
+ Message = "用户被禁用",
+ OpenId = wechatSession.OpenId
+ };
+
+ return Ok(resultDto);
+ }
+ else if (thirdUserEnt.AbpUserId == null)
+ {
+ resultDto = new ThirdLoginDto
+ {
+ IsToken = "N",
+ Message = "用户未授权",
+ OpenId = wechatSession.OpenId
+ };
+
+ return Ok(resultDto);
}
+
+
// 查询关联的 AbpUser
var abpUser = await _identityUserRepository.FirstOrDefaultAsync(f => f.Id == thirdUserEnt.AbpUserId);
if (abpUser == null)
{
- throw new UserFriendlyException("用户未关联权限");
+ resultDto = new ThirdLoginDto
+ {
+ IsToken = "N",
+ Message = "用户未关联权限",
+ OpenId = wechatSession.OpenId
+ };
+
+ return Ok(resultDto);
}
// 生成声明主体
@@ -81,40 +139,41 @@ namespace Shentun.Peis.Controllers
await SetClaimsDestinationsAsync(principal);
return SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
+
}
- else if (grantType == "phone_verify")
- {
- //手机号+验证码登录认证
+ //else if (grantType == "phone_verify")
+ //{
+ // //手机号+验证码登录认证
- var mobilePhone = request.GetParameter("mobilePhone").ToString();
- var verifyCode = request.GetParameter("verifyCode").ToString();
+ // var mobilePhone = request.GetParameter("mobilePhone").ToString();
+ // var verifyCode = request.GetParameter("verifyCode").ToString();
- var thirdUserEnt = await _thirdUserRepository.FirstOrDefaultAsync(f => f.MobilePhone == mobilePhone && f.IsActive == 'Y' && f.AbpUserId != null);
- if (thirdUserEnt == null)
- {
- throw new UserFriendlyException("用户未授权");
- }
- // 查询关联的 AbpUser
- var abpUser = await _identityUserRepository.FirstOrDefaultAsync(f => f.Id == thirdUserEnt.AbpUserId);
- if (abpUser == null)
- {
- throw new UserFriendlyException("用户未关联权限");
- }
+ // var thirdUserEnt = await _thirdUserRepository.FirstOrDefaultAsync(f => f.MobilePhone == mobilePhone && f.IsActive == 'Y' && f.AbpUserId != null);
+ // if (thirdUserEnt == null)
+ // {
+ // throw new UserFriendlyException("用户未授权");
+ // }
+ // // 查询关联的 AbpUser
+ // var abpUser = await _identityUserRepository.FirstOrDefaultAsync(f => f.Id == thirdUserEnt.AbpUserId);
+ // if (abpUser == null)
+ // {
+ // throw new UserFriendlyException("用户未关联权限");
+ // }
- // 生成声明主体
- var principal = await _signInManager.CreateUserPrincipalAsync(abpUser);
+ // // 生成声明主体
+ // var principal = await _signInManager.CreateUserPrincipalAsync(abpUser);
- var scopes = request.GetScopes();
- var resources = await GetResourcesAsync(scopes);
- principal.SetScopes(scopes);
- principal.SetResources(resources);
+ // var scopes = request.GetScopes();
+ // var resources = await GetResourcesAsync(scopes);
+ // principal.SetScopes(scopes);
+ // principal.SetResources(resources);
- await SetClaimsDestinationsAsync(principal);
+ // await SetClaimsDestinationsAsync(principal);
- return SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
- }
+ // return SignIn(principal, OpenIddictServerAspNetCoreDefaults.AuthenticationScheme);
+ //}
else
{
return await base.HandleAsync();