Files
tiku-backend.net/Tiku.Infrastructure/Commerce/Coupons/CommerceAdminService.Coupons.cs
xiong c497a3ca8d
Some checks failed
ci / release-gate (push) Has been cancelled
清理代码
2026-08-03 12:31:39 +08:00

93 lines
3.9 KiB
C#

using Microsoft.EntityFrameworkCore;
using Tiku.Application.Commerce;
using Tiku.Domain.Commerce;
namespace Tiku.Infrastructure.Commerce;
internal sealed partial class CommerceAdminService
{
public async Task<TenantCouponList> GetCouponsAsync(
CommerceAdminActor actor,
CommerceAdminQuery query,
CancellationToken cancellationToken = default)
{
await AssertAdminAsync(actor, cancellationToken);
var coupons = dbContext.Coupons.AsNoTracking()
.Where(item => item.TenantId == actor.TenantId);
var items = await coupons
.OrderByDescending(item => item.CreatedAt)
.Take(Math.Clamp(query.Limit ?? 50, 1, 200))
.ToArrayAsync(cancellationToken);
return new TenantCouponList(items);
}
public async Task<Coupon> UpsertCouponAsync(
CommerceAdminActor actor,
UpsertCouponCommand command,
CancellationToken cancellationToken = default)
{
await AssertAdminAsync(actor, cancellationToken);
var coupon = command.Id.HasValue
? await dbContext.Coupons.SingleOrDefaultAsync(
item => item.TenantId == actor.TenantId && item.Id == command.Id.Value,
cancellationToken)
: await dbContext.Coupons.SingleOrDefaultAsync(
item => item.TenantId == actor.TenantId && item.Code == command.Code.Trim(),
cancellationToken);
if (coupon is null)
{
coupon = new Coupon { TenantId = actor.TenantId };
dbContext.Coupons.Add(coupon);
}
coupon.Code = command.Code.Trim();
coupon.PlanId = command.PlanId;
coupon.DiscountType = command.DiscountType;
coupon.DiscountValue = command.DiscountValue;
coupon.ValidFrom = command.ValidFrom;
coupon.ValidTo = command.ValidTo;
coupon.MaxUses = command.MaxUses;
coupon.Source = command.Source?.Trim();
coupon.Remark = command.Remark;
await dbContext.SaveChangesAsync(cancellationToken);
return coupon;
}
public async Task<TenantCouponRedemptionList> GetCouponRedemptionsAsync(
CommerceAdminActor actor,
CommerceAdminQuery query,
CancellationToken cancellationToken = default)
{
await AssertAdminAsync(actor, cancellationToken);
var redemptions = dbContext.CouponRedemptions.AsNoTracking()
.Where(item => item.TenantId == actor.TenantId);
if (!string.IsNullOrWhiteSpace(query.Status))
redemptions = redemptions.Where(item => item.Status == ParseCouponRedemptionStatus(query.Status));
var items = await redemptions
.OrderByDescending(item => item.CreatedAt)
.Take(Math.Clamp(query.Limit ?? 50, 1, 200))
.ToArrayAsync(cancellationToken);
return new TenantCouponRedemptionList(items);
}
public async Task<TenantCouponReport> GetCouponReportAsync(
CommerceAdminActor actor,
CommerceAdminQuery query,
CancellationToken cancellationToken = default)
{
await AssertAdminAsync(actor, cancellationToken);
var couponCount =
await dbContext.Coupons.CountAsync(item => item.TenantId == actor.TenantId, cancellationToken);
var redemptions = dbContext.CouponRedemptions.AsNoTracking()
.Where(item => item.TenantId == actor.TenantId);
var claimedCount = await redemptions.CountAsync(cancellationToken);
var usedCount =
await redemptions.CountAsync(item => item.Status == CouponRedemptionStatus.Used, cancellationToken);
var discountApplied = await redemptions
.Where(item => item.Status == CouponRedemptionStatus.Used)
.SumAsync(item => item.DiscountAppliedCents, cancellationToken) ?? 0;
return new TenantCouponReport(couponCount, claimedCount, usedCount, discountApplied);
}
}