Browse Source

Merge pull request #1130 from colinin/change-user-avatar

feat(account): 增加用户头像更改接口
pull/1149/head
yx lin 1 year ago
committed by GitHub
parent
commit
e5c9900b7f
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 12
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/ChangePictureInput.cs
  2. 96
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/IAccountAppService.cs
  3. 4
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/IMyClaimAppService.cs
  4. 12
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/IMyProfileAppService.cs
  5. 1
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN.Abp.Account.Application.csproj
  6. 2
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AbpAccountApplicationModule.cs
  7. 8
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountContainer.cs
  8. 1
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyClaimAppService.cs
  9. 68
      aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyProfileAppService.cs
  10. 15
      aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/MyProfileController.cs

12
aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/Dto/ChangePictureInput.cs

@ -0,0 +1,12 @@
using System.ComponentModel.DataAnnotations;
using Volo.Abp.Auditing;
using Volo.Abp.Content;
namespace LINGYUN.Abp.Account;
public class ChangePictureInput
{
[Required]
[DisableAuditing]
public IRemoteStreamContent File { get; set; }
}

96
aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/IAccountAppService.cs

@ -1,58 +1,58 @@
using System.Threading.Tasks;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
namespace LINGYUN.Abp.Account;
public interface IAccountAppService : IApplicationService
{
/// <summary>
/// 通过手机号注册用户账户
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task RegisterAsync(PhoneRegisterDto input);
/// <summary>
/// 通过微信小程序注册用户账户
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task RegisterAsync(WeChatRegisterDto input);
/// <summary>
/// 通过手机号重置用户密码
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task ResetPasswordAsync(PhoneResetPasswordDto input);
/// <summary>
/// 发送手机注册验证码短信
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task SendPhoneRegisterCodeAsync(SendPhoneRegisterCodeDto input);
/// <summary>
/// 发送手机登录验证码短信
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task SendPhoneSigninCodeAsync(SendPhoneSigninCodeDto input);
using Volo.Abp.Application.Services;
namespace LINGYUN.Abp.Account;
public interface IAccountAppService : IApplicationService
{
/// <summary>
/// 通过手机号注册用户账户
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task RegisterAsync(PhoneRegisterDto input);
/// <summary>
/// 通过微信小程序注册用户账户
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task RegisterAsync(WeChatRegisterDto input);
/// <summary>
/// 通过手机号重置用户密码
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task ResetPasswordAsync(PhoneResetPasswordDto input);
/// <summary>
/// 发送手机注册验证码短信
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task SendPhoneRegisterCodeAsync(SendPhoneRegisterCodeDto input);
/// <summary>
/// 发送手机登录验证码短信
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task SendPhoneSigninCodeAsync(SendPhoneSigninCodeDto input);
/// <summary>
/// 发送邮件登录验证码
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task SendEmailSigninCodeAsync(SendEmailSigninCodeDto input);
/// <summary>
/// 发送手机重置密码验证码短信
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task SendPhoneResetPasswordCodeAsync(SendPhoneResetPasswordCodeDto input);
/// <returns></returns>
Task SendEmailSigninCodeAsync(SendEmailSigninCodeDto input);
/// <summary>
/// 发送手机重置密码验证码短信
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task SendPhoneResetPasswordCodeAsync(SendPhoneResetPasswordCodeDto input);
/// <summary>
/// 获取用户二次认证提供者列表
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
Task<ListResultDto<NameValue>> GetTwoFactorProvidersAsync(GetTwoFactorProvidersInput input);
}
/// <returns></returns>
Task<ListResultDto<NameValue>> GetTwoFactorProvidersAsync(GetTwoFactorProvidersInput input);
}

4
aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/IMyClaimAppService.cs

@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;
namespace LINGYUN.Abp.Account;
@ -10,6 +11,7 @@ public interface IMyClaimAppService : IApplicationService
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[Obsolete("请使用 IMyProfileAppService.ChangePictureAsync")]
Task ChangeAvatarAsync(ChangeAvatarInput input);
/// <summary>
/// 查询绑定状态

12
aspnet-core/modules/account/LINGYUN.Abp.Account.Application.Contracts/LINGYUN/Abp/Account/IMyProfileAppService.cs

@ -1,7 +1,9 @@
using LINGYUN.Abp.Identity;
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Dtos;
using Volo.Abp.Application.Services;
using Volo.Abp.Content;
namespace LINGYUN.Abp.Account;
@ -73,4 +75,14 @@ public interface IMyProfileAppService : IApplicationService
/// <param name="input"></param>
/// <returns></returns>
Task ConfirmEmailAsync(ConfirmEmailInput input);
/// <summary>
/// 变更用户头像
/// </summary>
/// <returns></returns>
Task ChangePictureAsync(ChangePictureInput input);
/// <summary>
/// 获取用户头像
/// </summary>
/// <returns></returns>
Task<IRemoteStreamContent> GetPictureAsync();
}

1
aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN.Abp.Account.Application.csproj

@ -15,6 +15,7 @@
<ItemGroup>
<PackageReference Include="Volo.Abp.Account.Application" />
<PackageReference Include="Volo.Abp.BlobStoring" />
<PackageReference Include="Volo.Abp.Sms" />
</ItemGroup>

2
aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AbpAccountApplicationModule.cs

@ -5,6 +5,7 @@ using LINGYUN.Abp.WeChat.MiniProgram;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Account.Localization;
using Volo.Abp.AutoMapper;
using Volo.Abp.BlobStoring;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.UI.Navigation.Urls;
@ -17,6 +18,7 @@ namespace LINGYUN.Abp.Account;
typeof(AbpAccountApplicationContractsModule),
typeof(AbpAccountEmailingModule),
typeof(AbpIdentityDomainModule),
typeof(AbpBlobStoringModule),
typeof(AbpWeChatMiniProgramModule))]
public class AbpAccountApplicationModule : AbpModule
{

8
aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/AccountContainer.cs

@ -0,0 +1,8 @@
using Volo.Abp.BlobStoring;
namespace LINGYUN.Abp.Account;
[BlobContainerName("users")]
public class AccountContainer
{
}

1
aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyClaimAppService.cs

@ -1,6 +1,7 @@
using LINGYUN.Abp.Identity;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;

68
aspnet-core/modules/account/LINGYUN.Abp.Account.Application/LINGYUN/Abp/Account/MyProfileAppService.cs

@ -7,17 +7,23 @@ using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Options;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Claims;
using System.Text;
using System.Threading.Tasks;
using System.Web;
using Volo.Abp;
using Volo.Abp.Account.Localization;
using Volo.Abp.Application.Dtos;
using Volo.Abp.BlobStoring;
using Volo.Abp.Caching;
using Volo.Abp.Content;
using Volo.Abp.Data;
using Volo.Abp.Identity;
using Volo.Abp.Security.Claims;
using Volo.Abp.Settings;
using Volo.Abp.Users;
using IIdentitySessionRepository = LINGYUN.Abp.Identity.IIdentitySessionRepository;
@ -36,6 +42,8 @@ public class MyProfileAppService : AccountApplicationServiceBase, IMyProfileAppS
protected IIdentitySessionManager IdentitySessionManager => LazyServiceProvider.LazyGetRequiredService<IIdentitySessionManager>();
protected IIdentitySessionRepository IdentitySessionRepository => LazyServiceProvider.LazyGetRequiredService<IIdentitySessionRepository>();
protected IBlobContainer<AccountContainer> AccountBlobContainer => LazyServiceProvider.LazyGetRequiredService<IBlobContainer<AccountContainer>>();
public MyProfileAppService(
Identity.IIdentityUserRepository userRepository,
IAccountSmsSecurityCodeSender securityCodeSender,
@ -50,6 +58,66 @@ public class MyProfileAppService : AccountApplicationServiceBase, IMyProfileAppS
LocalizationResource = typeof(AccountResource);
}
public async virtual Task ChangePictureAsync(ChangePictureInput input)
{
var user = await GetCurrentUserAsync();
var pictureId = input.File.FileName ?? $"{GuidGenerator.Create():n}.jpg";
var avatarClaims = user.Claims.Where(x => x.ClaimType.StartsWith(AbpClaimTypes.Picture))
.Select(x => x.ToClaim())
.Skip(0)
.Take(3)
.ToList();
if (avatarClaims.Any())
{
// 保留最多3个头像
if (avatarClaims.Count >= 3)
{
user.RemoveClaim(avatarClaims.First());
avatarClaims.RemoveAt(0);
}
// 历史头像加数字标识
for (var index = 1; index <= avatarClaims.Count; index++)
{
var avatarClaim = avatarClaims[index - 1];
var findClaim = user.FindClaim(avatarClaim);
if (findClaim != null)
{
findClaim.SetClaim(new Claim(
AbpClaimTypes.Picture + index.ToString(),
findClaim.ClaimValue));
}
}
}
user.AddClaim(GuidGenerator, new Claim(AbpClaimTypes.Picture, pictureId));
(await UserManager.UpdateAsync(user)).CheckErrors();
var pictureName = $"{user.Id:n}/avatar/{pictureId}";
await AccountBlobContainer.SaveAsync(pictureName, input.File.GetStream(), true);
await CurrentUnitOfWork.SaveChangesAsync();
}
public async virtual Task<IRemoteStreamContent> GetPictureAsync()
{
var currentUser = await GetCurrentUserAsync();
var pictureCalim = currentUser.Claims.FirstOrDefault(x => x.ClaimType == AbpClaimTypes.Picture);
if (pictureCalim?.ClaimValue.IsNullOrWhiteSpace() == true)
{
return new RemoteStreamContent(Stream.Null);
}
var pictureName = $"{CurrentUser.GetId():n}/avatar/{pictureCalim.ClaimValue}";
var stream = await AccountBlobContainer.GetOrNullAsync(pictureName);
return new RemoteStreamContent(stream, contentType: "image/jpeg");
}
public async virtual Task<PagedResultDto<IdentitySessionDto>> GetSessionsAsync(GetMySessionsInput input)
{
var user = await GetCurrentUserAsync();

15
aspnet-core/modules/account/LINGYUN.Abp.Account.HttpApi/LINGYUN/Abp/Account/MyProfileController.cs

@ -7,6 +7,7 @@ using Volo.Abp;
using Volo.Abp.Account;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Content;
namespace LINGYUN.Abp.Account;
@ -101,4 +102,18 @@ public class MyProfileController : AbpControllerBase, IMyProfileAppService
{
return MyProfileAppService.ResetAuthenticatorAsync();
}
[HttpPost]
[Route("picture")]
public virtual Task ChangePictureAsync([FromForm] ChangePictureInput input)
{
return MyProfileAppService.ChangePictureAsync(input);
}
[HttpGet]
[Route("picture")]
public virtual Task<IRemoteStreamContent> GetPictureAsync()
{
return MyProfileAppService.GetPictureAsync();
}
}

Loading…
Cancel
Save