修改User模块

This commit is contained in:
chfei committed 2026-10-23 19:01:28 +08:00
1 parent d6471f97d3
commit bb7162aaf6
21 files changed
+278 -336

No files matched your search

@@ -1,3 +1,5 @@
using MAX.Framework.Security;
using Store.Users.Services;
using MAX.Framework.Commons;
using MAX.Framework.Mediation;
using MediatR;
@@ -5,9 +7,9 @@ using Store.Users.Entities;
namespace Store.Users.Behaviors;
/// <summary>锁定积分账户并检查消费额度,不依赖商铺信息。</summary>
/// <summary>从登录上下文确认操作者,校验目标账户归属后锁定积分账户并检查消费额度。</summary>
public sealed class AccountConsumptionBehavior<TRequest, TResponse>(
UnitOfWorkExecutionContext executionContext)
UnitOfWorkExecutionContext executionContext, ICurrentUser currentUser)
: IPipelineBehavior<TRequest, TResponse>
where TRequest : class, IRequest<TResponse>, IAccountConsumptionRequest
{
@@ -15,22 +17,26 @@ public sealed class AccountConsumptionBehavior<TRequest, TResponse>(
RequestHandlerDelegate<TResponse> next)
{
cancellationToken.ThrowIfCancellationRequested();
if (string.IsNullOrWhiteSpace(request.UserName))
throw new AppException("用户名不能为空");
var userName = request.UserName.Trim();
var user = await executionContext.Orm.Select<UserEntity>().Where(a => a.UserName == userName)
.ForUpdate().FirstAsync(cancellationToken)
?? throw new AppException("不存在的用户");
if (!currentUser.IsAuthenticated || string.IsNullOrWhiteSpace(currentUser.UserName))
throw new UnauthorizedAccessException();
var orm = executionContext.Orm;
var actor = await orm.Select<UserEntity>().Where(u => u.UserName == currentUser.UserName)
.FirstAsync(cancellationToken) ?? throw new UnauthorizedAccessException("登录账户不存在");
var userName = string.IsNullOrWhiteSpace(request.UserName) ? actor.UserName : request.UserName.Trim();
var user = await orm.Select<UserEntity>().Where(u => u.UserName == userName)
.ForUpdate().FirstAsync(cancellationToken) ?? throw new AppException("用户不存在");
if (!UserAccessPolicy.CanUseSelfService(actor, user))
throw new AppException("无权为该账户续费", 403);
var quote = request.CalculateConsumption(user);
if (quote.Amount <= 0 || quote.UnitPrice <= 0)
throw new AppException("消费金额必须大于0");
if (user.Points < quote.Amount)
throw new AppException("余额不足");
throw new AppException("积分不足");
lock (request)
{
if (request.ConsumptionContext != null)
throw new InvalidOperationException("同一个消费命令不能同时执行");
request.ConsumptionContext = new AccountConsumptionContext(user, quote);
request.ConsumptionContext = new AccountConsumptionContext(user, actor, quote);
}
try
{
@@ -6,7 +6,7 @@ namespace Store.Users.Behaviors;
/// <summary>需要账户积分消费检查的请求。</summary>
public interface IAccountConsumptionRequest
{
string UserName { get; }
string? UserName { get; }
AccountConsumptionContext? ConsumptionContext { get; set; }
ConsumptionQuote CalculateConsumption(UserEntity user);
}
@@ -20,4 +20,4 @@ public interface IShopOwnershipRequest
}
public sealed record ConsumptionQuote(decimal Amount, decimal UnitPrice);
public sealed record AccountConsumptionContext(UserEntity User, ConsumptionQuote Quote);
public sealed record AccountConsumptionContext(UserEntity User, UserEntity Actor, ConsumptionQuote Quote);
@@ -14,8 +14,6 @@ public sealed class ShopOwnershipBehavior<TRequest, TResponse>(
RequestHandlerDelegate<TResponse> next)
{
cancellationToken.ThrowIfCancellationRequested();
if (string.IsNullOrWhiteSpace(request.UserName) || string.IsNullOrWhiteSpace(request.ShopId))
throw new AppException("用户名和商铺ID不能为空");
var userName = request.UserName.Trim();
var shopId = request.ShopId.Trim();
var orm = executionContext.IsActive ? executionContext.Orm : freeSql;
@@ -23,8 +21,6 @@ public sealed class ShopOwnershipBehavior<TRequest, TResponse>(
if (executionContext.IsActive) query = query.ForUpdate();
var shop = await query.FirstAsync(cancellationToken)
?? throw new AppException("不存在的商铺或该商铺不属于当前用户");
if (!string.Equals(shop.UserName, userName, StringComparison.OrdinalIgnoreCase))
throw new AppException("该商铺不属于当前用户");
lock (request)
{
if (request.OwnedShop != null)