Skip to content

Commit

Permalink
feat(account): 增加用户头像更改接口
Browse files Browse the repository at this point in the history
  • Loading branch information
colinin committed Mar 5, 2025
1 parent 9a785f7 commit 101dbd5
Show file tree
Hide file tree
Showing 10 changed files with 168 additions and 49 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using Volo.Abp.Auditing;
using Volo.Abp.Content;

namespace LINGYUN.Abp.Account;

public class ChangePictureInput
{
[DisableAuditing]
public IRemoteStreamContent File { get; set; }
}
Original file line number Diff line number Diff line change
@@ -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);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System;
using System.Threading.Tasks;
using Volo.Abp.Application.Services;

namespace LINGYUN.Abp.Account;
Expand All @@ -10,6 +11,7 @@ public interface IMyClaimAppService : IApplicationService
/// </summary>
/// <param name="input"></param>
/// <returns></returns>
[Obsolete("请使用 IMyProfileAppService.ChangePictureAsync")]
Task ChangeAvatarAsync(ChangeAvatarInput input);
/// <summary>
/// 查询绑定状态
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -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();
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

<ItemGroup>
<PackageReference Include="Volo.Abp.Account.Application" />
<PackageReference Include="Volo.Abp.BlobStoring" />
<PackageReference Include="Volo.Abp.Sms" />
</ItemGroup>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
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;
Expand All @@ -17,6 +18,7 @@ namespace LINGYUN.Abp.Account;
typeof(AbpAccountApplicationContractsModule),
typeof(AbpAccountEmailingModule),
typeof(AbpIdentityDomainModule),
typeof(AbpBlobStoringModule),
typeof(AbpWeChatMiniProgramModule))]
public class AbpAccountApplicationModule : AbpModule
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
using Volo.Abp.BlobStoring;

namespace LINGYUN.Abp.Account;

[BlobContainerName("users")]
public class AccountContainer
{
}
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,23 @@
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;
Expand All @@ -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,
Expand All @@ -50,6 +58,66 @@ public MyProfileAppService(
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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Volo.Abp.Account;
using Volo.Abp.Application.Dtos;
using Volo.Abp.AspNetCore.Mvc;
using Volo.Abp.Content;

namespace LINGYUN.Abp.Account;

Expand Down Expand Up @@ -101,4 +102,18 @@ public virtual Task ResetAuthenticatorAsync()
{
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();
}
}

0 comments on commit 101dbd5

Please sign in to comment.