using System.ComponentModel.DataAnnotations; using System.Text.Json; using Tiku.Application.PlatformBilling; using Tiku.Domain.Platform; namespace Tiku.Api.Contracts; /// /// 新增或更新SaaS功能请求 DTO。 /// public sealed record UpsertSaasFeatureDto( Guid? Id, [Required, MaxLength(120)] string Code, [Required, MaxLength(200)] string Name, [Required, MaxLength(100)] string Category, [MaxLength(1000)] string? Description, [Range(0, int.MaxValue)] int ReferencePriceCents, [Required, MaxLength(10)] string Currency, SaasFeatureStatus Status, int SortOrder) { public UpsertSaasFeatureCommand ToCommand() => new(Id, Code, Name, Category, Description, ReferencePriceCents, Currency, Status, SortOrder); } /// /// 新增或更新SaaS套餐请求 DTO。 /// public sealed record UpsertSaasOfferingDto( Guid? Id, [Required, MaxLength(120)] string Code, [Required, MaxLength(200)] string Name, SaasOfferingType Type, SaasOfferingStatus Status, [MaxLength(1000)] string? Description, int SortOrder) { public UpsertSaasOfferingCommand ToCommand() => new(Id, Code, Name, Type, Status, Description, SortOrder); } /// /// 新增或更新 SaaS 功能额度定义。 /// public sealed record UpsertSaasFeatureLimitDto( Guid? Id, [Required, MaxLength(120)] string MetricCode, [Required, MaxLength(120)] string FeatureCode, [Required, MaxLength(200)] string Name, [Required, MaxLength(50)] string Unit, SaasFeatureLimitKind Kind, [Range(1, 100)] int WarningPercent, bool IsHardLimit) { public UpsertSaasFeatureLimitCommand ToCommand() => new( Id, MetricCode, FeatureCode, Name, Unit, Kind, WarningPercent, IsHardLimit); } /// /// 新增或更新SaaS套餐版本请求 DTO。 /// public sealed record UpsertSaasOfferingVersionDto( Guid? Id, Guid OfferingId, PlatformBillingCycle BillingCycle, [Range(0, int.MaxValue)] int OriginalAmountCents, [Range(0, int.MaxValue)] int AmountCents, [Required, MaxLength(10)] string Currency, DateTimeOffset? EffectiveAt, IReadOnlyCollection? FeatureCodes, IReadOnlyDictionary? Limits, JsonElement Metadata) { public UpsertSaasOfferingVersionCommand ToCommand() => new( Id, OfferingId, BillingCycle, OriginalAmountCents, AmountCents, Currency, EffectiveAt, FeatureCodes ?? [], Limits ?? new Dictionary(), Metadata); } /// /// 创建平台账务报价请求 DTO。 /// public sealed record CreatePlatformBillingQuoteDto( Guid BaseOfferingVersionId, IReadOnlyCollection? AddOnOfferingVersionIds, PlatformBillingOrderPurpose Purpose, [Required, MaxLength(200)] string IdempotencyKey) { public CreatePlatformBillingQuoteCommand ToCommand() => new(BaseOfferingVersionId, AddOnOfferingVersionIds ?? [], Purpose, IdempotencyKey); } /// /// 创建平台账务订单请求 DTO。 /// public sealed record CreatePlatformBillingOrderDto(Guid QuoteId, [Required, MaxLength(200)] string IdempotencyKey) { public CreatePlatformBillingOrderCommand ToCommand() => new(QuoteId, IdempotencyKey); } /// /// 创建平台账务支付请求 DTO。 /// public sealed record CreatePlatformBillingPaymentDto( [Required, MaxLength(50)] string Provider, [Required, MaxLength(50)] string Method, [Required, MaxLength(200)] string IdempotencyKey, string? OpenId, string? ReturnUrl, string? QuitUrl) { public CreatePlatformBillingPaymentCommand ToCommand(string orderNo) => new(orderNo, Provider, Method, IdempotencyKey, OpenId, ReturnUrl, QuitUrl); } /// /// 变更租户订阅请求 DTO。 /// public sealed record ChangeTenantSubscriptionDto( Guid BaseOfferingVersionId, IReadOnlyCollection? AddOnOfferingVersionIds, [Required, MaxLength(200)] string IdempotencyKey) { public ChangeTenantSubscriptionCommand ToCommand() => new(BaseOfferingVersionId, AddOnOfferingVersionIds ?? []); } /// /// Idempotent租户账务请求 DTO。 /// public sealed record IdempotentTenantBillingDto([Required, MaxLength(200)] string IdempotencyKey); /// /// 确认人工平台支付请求 DTO。 /// public sealed record ConfirmManualPlatformPaymentDto( Guid PaymentId, string? ProviderTradeNo, DateTimeOffset? PaidAt, [Required, MaxLength(1000)] string Reason) { public ConfirmManualPaymentCommand ToCommand() => new(PaymentId, ProviderTradeNo, PaidAt, Reason); } /// /// 新增或更新租户功能覆盖规则请求 DTO。 /// public sealed record UpsertTenantFeatureOverrideDto( Guid TenantId, [Required, MaxLength(120)] string FeatureCode, TenantFeatureOverrideMode Mode, DateTimeOffset? ExpiresAt, [Required, MaxLength(1000)] string Reason) { public UpsertTenantFeatureOverrideCommand ToCommand() => new(TenantId, FeatureCode, Mode, ExpiresAt, Reason); }