feat: add process expired points command
This commit is contained in:
parent
4745c91915
commit
ce6b80e334
@ -0,0 +1,5 @@
|
||||
using MediatR;
|
||||
|
||||
namespace Fengling.Member.Application.Commands.Points;
|
||||
|
||||
public record ProcessExpiredPointsCommand(int BatchSize = 1000) : IRequest<int>;
|
||||
@ -0,0 +1,49 @@
|
||||
using MediatR;
|
||||
using Fengling.Member.Domain.Aggregates.PointsModel;
|
||||
using Fengling.Member.Infrastructure;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace Fengling.Member.Application.Commands.Points;
|
||||
|
||||
public class ProcessExpiredPointsCommandHandler : IRequestHandler<ProcessExpiredPointsCommand, int>
|
||||
{
|
||||
private readonly ApplicationDbContext _context;
|
||||
|
||||
public ProcessExpiredPointsCommandHandler(ApplicationDbContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
|
||||
public async Task<int> Handle(ProcessExpiredPointsCommand request, CancellationToken cancellationToken)
|
||||
{
|
||||
var now = DateTime.UtcNow;
|
||||
|
||||
var expiredTransactions = await _context.PointsTransactions
|
||||
.Where(x => x.ExpireAt <= now
|
||||
&& x.ExpireAt > DateTime.MinValue
|
||||
&& x.Points > 0)
|
||||
.OrderBy(x => x.ExpireAt)
|
||||
.Take(request.BatchSize)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
foreach (var transaction in expiredTransactions)
|
||||
{
|
||||
var deduction = PointsTransaction.Create(
|
||||
transaction.PointsAccountId,
|
||||
transaction.MemberId,
|
||||
-transaction.Points,
|
||||
"Expired",
|
||||
$"来源交易: {transaction.Id}",
|
||||
PointsTransactionType.Expired,
|
||||
$"积分过期扣除 - 来源交易: {transaction.Id}");
|
||||
|
||||
deduction.SetExpireAt(transaction.ExpireAt);
|
||||
|
||||
_context.PointsTransactions.Add(deduction);
|
||||
}
|
||||
|
||||
var affected = await _context.SaveChangesAsync(cancellationToken);
|
||||
|
||||
return affected / 2;
|
||||
}
|
||||
}
|
||||
@ -10,11 +10,17 @@ public class PointsTransaction : Entity<long>
|
||||
public PointsTransactionType TransactionTypeCategory { get; private set; }
|
||||
public string? Remark { get; private set; }
|
||||
public DateTime CreatedAt { get; private set; } = DateTime.UtcNow;
|
||||
public DateTime ExpireAt { get; private set; } = DateTime.MinValue;
|
||||
|
||||
private PointsTransaction()
|
||||
{
|
||||
}
|
||||
|
||||
public void SetExpireAt(DateTime expireAt)
|
||||
{
|
||||
ExpireAt = expireAt;
|
||||
}
|
||||
|
||||
public static PointsTransaction Create(
|
||||
long pointsAccountId,
|
||||
long memberId,
|
||||
@ -41,5 +47,6 @@ public class PointsTransaction : Entity<long>
|
||||
public enum PointsTransactionType
|
||||
{
|
||||
Earn = 1,
|
||||
Deduct = 2
|
||||
Deduct = 2,
|
||||
Expired = 3
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ public partial class ApplicationDbContext(DbContextOptions<ApplicationDbContext>
|
||||
public DbSet<Fengling.Member.Domain.Aggregates.PointsModel.PointsAccount> PointsAccounts => Set<Fengling.Member.Domain.Aggregates.PointsModel.PointsAccount>();
|
||||
public DbSet<Fengling.Member.Domain.Aggregates.PointsRuleModel.PointsRule> PointsRules => Set<Fengling.Member.Domain.Aggregates.PointsRuleModel.PointsRule>();
|
||||
public DbSet<Fengling.Member.Domain.Aggregates.PointsRuleModel.PointsRuleCondition> PointsRuleConditions => Set<Fengling.Member.Domain.Aggregates.PointsRuleModel.PointsRuleCondition>();
|
||||
public DbSet<Fengling.Member.Domain.Aggregates.PointsModel.PointsTransaction> PointsTransactions => Set<Fengling.Member.Domain.Aggregates.PointsModel.PointsTransaction>();
|
||||
|
||||
protected override void OnModelCreating(ModelBuilder modelBuilder)
|
||||
{
|
||||
|
||||
Loading…
Reference in New Issue
Block a user