修改User模块
This commit is contained in:
1 parent
d6471f97d3
commit
bb7162aaf6
21 files changed
+278
-336
No files matched your search
@@ -18,27 +18,28 @@ namespace Store.Users.Commands;
|
||||
[MediatRBehavior(typeof(TransactionBehavior<,>))]
|
||||
[MediatRBehavior(typeof(AccountConsumptionBehavior<,>))]
|
||||
[MediatRBehavior(typeof(ShopOwnershipBehavior<,>))]
|
||||
public sealed record ShopRenewCommand(string UserName, string ShopId, int RenewDuration, string? Remark = null, string? OperatorName = null)
|
||||
public sealed record ShopRenewCommand(ShopRenewRequest Input)
|
||||
: IRequest<ShopRenewResponse>, IValidatableRequest, IAccountConsumptionRequest, IShopOwnershipRequest
|
||||
{
|
||||
// 由消费管道建立,仅在当前事务执行期间有效。
|
||||
AccountConsumptionContext? IAccountConsumptionRequest.ConsumptionContext { get; set; }
|
||||
// 请求只包含业务输入;实际操作者与目标账户由消费管道从数据库确定。
|
||||
public string? UserName => Input.UserName;
|
||||
public string ShopId => Input.ShopId;
|
||||
public int RenewDuration => Input.RenewDuration;
|
||||
public string? Remark => Input.Remark;
|
||||
private AccountConsumptionContext? consumptionContext;
|
||||
AccountConsumptionContext? IAccountConsumptionRequest.ConsumptionContext
|
||||
{
|
||||
get => consumptionContext;
|
||||
set => consumptionContext = value;
|
||||
}
|
||||
// 消费管道先于店铺管道执行,店铺校验使用已授权的账户名称。
|
||||
string IShopOwnershipRequest.UserName => consumptionContext!.User.UserName;
|
||||
ShopEntity? IShopOwnershipRequest.OwnedShop { get; set; }
|
||||
|
||||
void IValidatableRequest.Validate()
|
||||
{
|
||||
RequestValidator.Validate(new UserNameRequest { UserName = UserName?.Trim()! });
|
||||
UserInputChecks.Length(UserName.Trim(), 20, "用户名");
|
||||
UserInputChecks.Length(OperatorName, 20, "操作者");
|
||||
var request = new ShopRenewRequest { ShopId = ShopId, RenewDuration = RenewDuration, Remark = Remark };
|
||||
RequestValidator.Validate(request);
|
||||
UserInputChecks.Renew(request);
|
||||
}
|
||||
void IValidatableRequest.Validate() => RequestValidator.Validate(Input);
|
||||
|
||||
ConsumptionQuote IAccountConsumptionRequest.CalculateConsumption(UserEntity user)
|
||||
{
|
||||
if (RenewDuration is < 1 or > 120)
|
||||
throw new AppException("续费时长必须为1-120个月");
|
||||
int price = Math.Max(30, user.ShopPointsPerMonth);
|
||||
return new ConsumptionQuote((decimal)price * RenewDuration, price);
|
||||
}
|
||||
@@ -49,9 +50,7 @@ internal sealed class ShopRenewCommandHandler(UnitOfWorkExecutionContext executi
|
||||
{
|
||||
public async Task<ShopRenewResponse> Handle(ShopRenewCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(request);
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
var userName = request.UserName.Trim();
|
||||
var shopId = request.ShopId.Trim();
|
||||
var remark = string.IsNullOrWhiteSpace(request.Remark) ? null : request.Remark.Trim();
|
||||
|
||||
@@ -59,12 +58,8 @@ internal sealed class ShopRenewCommandHandler(UnitOfWorkExecutionContext executi
|
||||
?? throw new InvalidOperationException("续费命令必须通过账户消费管道执行");
|
||||
var orm = executionContext.Orm;
|
||||
var user = context.User;
|
||||
// 代操作权限在事务中再次确认,审计流水记录实际操作者而非被操作账户。
|
||||
var operatorName = request.OperatorName ?? userName;
|
||||
var actor = await orm.Select<UserEntity>().Where(u => u.UserName == operatorName).FirstAsync(cancellationToken)
|
||||
?? throw new AppException("操作者账户不存在");
|
||||
if (!UserAccessPolicy.CanManage(actor, user) && actor.Id != user.Id)
|
||||
throw new AppException("无权为该账户续费", 403);
|
||||
var userName = user.UserName;
|
||||
var actor = context.Actor;
|
||||
var shop = ((IShopOwnershipRequest)request).OwnedShop
|
||||
?? throw new InvalidOperationException("续费命令必须通过商铺归属管道执行");
|
||||
decimal pointsPerMonth = context.Quote.UnitPrice;
|
||||
|
||||
Reference in new issue
Block a user