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

535 lines
17 KiB
C#

using System.Text.Json;
using Tiku.Domain.Common;
namespace Tiku.Domain.Commerce;
public sealed class Product : AuditableTenantEntity
{
public Guid? RegionId { get; set; }
public string? LegacyId { get; set; }
public string Title { get; set; } = string.Empty;
public string? LegacyPriceText { get; set; }
public string? Link { get; set; }
public ProductType Type { get; set; } = ProductType.Material;
public JsonElement Tags { get; set; } = JsonDefaults.Array();
public int SortOrder { get; set; }
public string? Cover { get; set; }
public string? PreviewIframe { get; set; }
public JsonElement DetailImages { get; set; } = JsonDefaults.Array();
public bool IsActive { get; set; } = true;
}
public sealed class SvipPlan : AuditableTenantEntity
{
public Guid? RegionId { get; set; }
public string? LegacyId { get; set; }
public string Name { get; set; } = string.Empty;
public int PriceCents { get; set; }
public int? OriginalPriceCents { get; set; }
public int Days { get; set; }
public string? Description { get; set; }
public string? PerDayLabel { get; set; }
public string? Badge { get; set; }
public bool Recommended { get; set; }
public bool CouponOnly { get; set; }
public string? VpProductId { get; set; }
public bool VpEnabled { get; set; }
public int SortOrder { get; set; }
public bool IsActive { get; set; } = true;
}
public sealed class Order : AuditableTenantEntity
{
public Guid? UserId { get; set; }
public Guid? PlanId { get; set; }
public Guid? RegionId { get; set; }
public string? LegacyId { get; set; }
public string? LegacyUserId { get; set; }
public string? LegacyPlanId { get; set; }
public string? LegacyRegionId { get; set; }
public string OrderNo { get; set; } = string.Empty;
public OrderStatus Status { get; set; } = OrderStatus.Pending;
public string? ProductType { get; set; }
public string? ProductName { get; set; }
public int AmountCents { get; set; }
public string? PayMethod { get; set; }
public string? PayProvider { get; set; }
public string? TradeNo { get; set; }
public int? Days { get; set; }
public int RefundedAmountCents { get; set; }
public DateTimeOffset? PaidAt { get; set; }
public JsonElement RawPayload { get; set; } = JsonDefaults.Object();
}
public sealed class OrderItem : AuditableTenantEntity
{
public Guid OrderId { get; set; }
public string? LegacyId { get; set; }
public string ItemType { get; set; } = string.Empty;
public Guid? ItemId { get; set; }
public string Name { get; set; } = string.Empty;
public int Quantity { get; set; } = 1;
public int UnitAmountCents { get; set; }
public int TotalAmountCents { get; set; }
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}
public sealed class Payment : AuditableTenantEntity
{
public Guid OrderId { get; set; }
public string? LegacyId { get; set; }
public string? LegacyOrderId { get; set; }
public string Provider { get; set; } = string.Empty;
public string? Method { get; set; }
public PaymentStatus Status { get; set; } = PaymentStatus.Pending;
public int AmountCents { get; set; }
public int RefundedAmountCents { get; set; }
public string? ProviderTradeNo { get; set; }
public DateTimeOffset? PaidAt { get; set; }
public JsonElement RawPayload { get; set; } = JsonDefaults.Object();
}
public sealed class PaymentEvent : Entity, ITenantOwned
{
public Guid? PaymentId { get; set; }
public string Provider { get; set; } = string.Empty;
public string EventType { get; set; } = string.Empty;
public string? EventId { get; set; }
public bool? SignatureValid { get; set; }
public JsonElement Payload { get; set; } = JsonDefaults.Object();
public DateTimeOffset? ProcessedAt { get; set; }
public string? Error { get; set; }
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
public Guid TenantId { get; set; }
}
public sealed class Entitlement : Entity, ITenantOwned
{
public Guid UserId { get; set; }
public string EntitlementType { get; set; } = "svip";
public EntitlementScopeType ScopeType { get; set; } = EntitlementScopeType.Tenant;
public Guid? ScopeId { get; set; }
public string SourceType { get; set; } = "migration";
public Guid? SourceId { get; set; }
public string? LegacySourceId { get; set; }
public DateTimeOffset StartsAt { get; set; } = DateTimeOffset.UtcNow;
public DateTimeOffset? ExpiresAt { get; set; }
public EntitlementStatus Status { get; set; } = EntitlementStatus.Active;
public DateTimeOffset? RevokedAt { get; set; }
public Guid? RevokedBy { get; set; }
public string? RevokedReason { get; set; }
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
public Guid TenantId { get; set; }
}
public sealed class CodeBatch : AuditableTenantEntity
{
public Guid? RegionId { get; set; }
public Guid? CreatedBy { get; set; }
public string? LegacyId { get; set; }
public string Name { get; set; } = string.Empty;
public string? SaleType { get; set; }
public string? Channel { get; set; }
public string? CampaignName { get; set; }
public int DefaultUnitPriceCents { get; set; }
public int CostPriceCents { get; set; }
public int TotalCount { get; set; }
public int? Days { get; set; }
public string? LegacyRegionId { get; set; }
public DateTimeOffset? IssuedAt { get; set; }
public string? Remark { get; set; }
public decimal? CommissionRate { get; set; }
}
public sealed class ActivationCode : AuditableTenantEntity
{
public Guid? UsedBy { get; set; }
public Guid? AgentUserId { get; set; }
public Guid? BatchId { get; set; }
public Guid? UsedRegionId { get; set; }
public Guid? CouponRedemptionId { get; set; }
public string? LegacyId { get; set; }
public string Code { get; set; } = string.Empty;
public int Days { get; set; }
public bool IsUsed { get; set; }
public DateTimeOffset? UsedAt { get; set; }
public string? SaleType { get; set; }
public int? UnitPriceCents { get; set; }
public string? SoldTo { get; set; }
public string? CouponCode { get; set; }
public string? Remark { get; set; }
}
public sealed class Coupon : AuditableTenantEntity
{
public Guid? PlanId { get; set; }
public string? LegacyId { get; set; }
public string Code { get; set; } = string.Empty;
public DiscountType? DiscountType { get; set; }
public decimal? DiscountValue { get; set; }
public DateTimeOffset? ValidFrom { get; set; }
public DateTimeOffset? ValidTo { get; set; }
public int? MaxUses { get; set; }
public int UsedCount { get; set; }
public string? Source { get; set; }
public string? Remark { get; set; }
}
public sealed class CouponRedemption : AuditableTenantEntity
{
public Guid? CouponId { get; set; }
public Guid? UserId { get; set; }
public Guid? PlanId { get; set; }
public Guid? OrderId { get; set; }
public Guid? RegionId { get; set; }
public string? LegacyId { get; set; }
public string? CouponCode { get; set; }
public CouponRedemptionStatus Status { get; set; } = CouponRedemptionStatus.Claimed;
public int? DiscountAppliedCents { get; set; }
public string? Source { get; set; }
public string? Remark { get; set; }
public DateTimeOffset? ClaimedAt { get; set; }
public DateTimeOffset? UsedAt { get; set; }
}
public sealed class CommerceRefundRequest : AuditableTenantEntity
{
public Guid OrderId { get; set; }
public Guid? PaymentId { get; set; }
public Guid? RequestedBy { get; set; }
public Guid? ReviewedBy { get; set; }
public Guid? ProcessedBy { get; set; }
public string RefundNo { get; set; } = string.Empty;
public string? Provider { get; set; }
public string? ProviderRefundNo { get; set; }
public CommerceRefundStatus Status { get; set; } = CommerceRefundStatus.Requested;
public int AmountCents { get; set; }
public string? Reason { get; set; }
public RefundEntitlementAction EntitlementAction { get; set; } = RefundEntitlementAction.RevokeOnSuccess;
public DateTimeOffset RequestedAt { get; set; } = DateTimeOffset.UtcNow;
public DateTimeOffset? ReviewedAt { get; set; }
public DateTimeOffset? ProcessedAt { get; set; }
public DateTimeOffset? SucceededAt { get; set; }
public DateTimeOffset? FailedAt { get; set; }
public DateTimeOffset? CancelledAt { get; set; }
public string? FailureReason { get; set; }
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}
public sealed class CommerceRefundEvent : Entity, ITenantOwned
{
public Guid RefundRequestId { get; set; }
public CommerceRefundStatus? FromStatus { get; set; }
public CommerceRefundStatus ToStatus { get; set; } = CommerceRefundStatus.Requested;
public string EventType { get; set; } = string.Empty;
public Guid? ActorUserId { get; set; }
public JsonElement Details { get; set; } = JsonDefaults.Object();
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
public Guid TenantId { get; set; }
}
public sealed class CommerceReconciliationBatch : AuditableTenantEntity
{
public Guid? CreatedBy { get; set; }
public string Provider { get; set; } = string.Empty;
public DateOnly BillDate { get; set; }
public ReconciliationBillType BillType { get; set; } = ReconciliationBillType.Combined;
public ReconciliationSource Source { get; set; } = ReconciliationSource.ManualUpload;
public string? SourceName { get; set; }
public string SourceHash { get; set; } = string.Empty;
public ReconciliationBatchStatus Status { get; set; } = ReconciliationBatchStatus.Completed;
public int TotalCount { get; set; }
public int MatchedCount { get; set; }
public int MismatchCount { get; set; }
public int MissingLocalCount { get; set; }
public int MissingProviderCount { get; set; }
public int DuplicateCount { get; set; }
public int IgnoredCount { get; set; }
public int AmountCents { get; set; }
public int RefundAmountCents { get; set; }
public int FeeCents { get; set; }
public DateTimeOffset? CompletedAt { get; set; }
public string? Error { get; set; }
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}
public sealed class CommerceReconciliationItem : Entity, ITenantOwned
{
public Guid BatchId { get; set; }
public Guid? OrderId { get; set; }
public Guid? PaymentId { get; set; }
public Guid? RefundRequestId { get; set; }
public int RowNo { get; set; }
public string Provider { get; set; } = string.Empty;
public ReconciliationTransactionType TransactionType { get; set; } = ReconciliationTransactionType.Payment;
public string? ProviderTradeNo { get; set; }
public string? ProviderRefundNo { get; set; }
public string? OrderNo { get; set; }
public string? RefundNo { get; set; }
public int AmountCents { get; set; }
public int RefundAmountCents { get; set; }
public int FeeCents { get; set; }
public DateTimeOffset? PaidAt { get; set; }
public DateTimeOffset? RefundedAt { get; set; }
public string? ProviderStatus { get; set; }
public string? LocalStatus { get; set; }
public ReconciliationMatchStatus MatchStatus { get; set; } = ReconciliationMatchStatus.Matched;
public NotificationSeverity Severity { get; set; } = NotificationSeverity.Info;
public string? IssueCode { get; set; }
public JsonElement Details { get; set; } = JsonDefaults.Object();
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
public Guid TenantId { get; set; }
}
public sealed class CommerceReconciliationIssue : AuditableTenantEntity
{
public Guid? BatchId { get; set; }
public Guid? ItemId { get; set; }
public Guid? OrderId { get; set; }
public Guid? PaymentId { get; set; }
public Guid? RefundRequestId { get; set; }
public Guid? AssignedTo { get; set; }
public Guid? CreatedBy { get; set; }
public Guid? ResolvedBy { get; set; }
public string IssueNo { get; set; } = string.Empty;
public string Provider { get; set; } = string.Empty;
public ReconciliationTransactionType TransactionType { get; set; } = ReconciliationTransactionType.Payment;
public string? IssueCode { get; set; }
public ReconciliationIssueMatchStatus MatchStatus { get; set; } = ReconciliationIssueMatchStatus.AmountMismatch;
public NotificationSeverity Severity { get; set; } = NotificationSeverity.Warning;
public ReconciliationIssueStatus Status { get; set; } = ReconciliationIssueStatus.Open;
public ReconciliationResolutionType ResolutionType { get; set; } = ReconciliationResolutionType.None;
public string? OrderNo { get; set; }
public string? RefundNo { get; set; }
public string? ProviderTradeNo { get; set; }
public string? ProviderRefundNo { get; set; }
public int AmountCents { get; set; }
public int RefundAmountCents { get; set; }
public DateTimeOffset? ResolvedAt { get; set; }
public DateTimeOffset? DueAt { get; set; }
public string? Summary { get; set; }
public string? ResolutionNote { get; set; }
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}
public sealed class CommerceReconciliationIssueEvent : Entity, ITenantOwned
{
public Guid IssueId { get; set; }
public ReconciliationIssueStatus? FromStatus { get; set; }
public ReconciliationIssueStatus? ToStatus { get; set; }
public string EventType { get; set; } = string.Empty;
public Guid? ActorUserId { get; set; }
public string? Note { get; set; }
public JsonElement Details { get; set; } = JsonDefaults.Object();
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
public Guid TenantId { get; set; }
}
public sealed class CommerceAdjustmentVoucher : AuditableTenantEntity
{
public Guid? IssueId { get; set; }
public Guid? BatchId { get; set; }
public Guid? ItemId { get; set; }
public Guid? OrderId { get; set; }
public Guid? PaymentId { get; set; }
public Guid? RefundRequestId { get; set; }
public Guid? CreatedBy { get; set; }
public Guid? ReviewedBy { get; set; }
public string VoucherNo { get; set; } = string.Empty;
public CommerceAdjustmentVoucherStatus Status { get; set; } = CommerceAdjustmentVoucherStatus.Draft;
public CommerceAdjustmentDirection Direction { get; set; } = CommerceAdjustmentDirection.IncreaseRevenue;
public int AmountCents { get; set; }
public string Currency { get; set; } = "CNY";
public string Reason { get; set; } = string.Empty;
public string? ProofAssetKey { get; set; }
public DateTimeOffset? ReviewedAt { get; set; }
public DateTimeOffset? ClosedAt { get; set; }
public JsonElement Metadata { get; set; } = JsonDefaults.Object();
}
public sealed class CommerceAdjustmentVoucherEvent : Entity, ITenantOwned
{
public Guid VoucherId { get; set; }
public CommerceAdjustmentVoucherStatus? FromStatus { get; set; }
public CommerceAdjustmentVoucherStatus ToStatus { get; set; } = CommerceAdjustmentVoucherStatus.Draft;
public Guid? ActorUserId { get; set; }
public string? Note { get; set; }
public JsonElement Details { get; set; } = JsonDefaults.Object();
public DateTimeOffset CreatedAt { get; set; } = DateTimeOffset.UtcNow;
public Guid TenantId { get; set; }
}
public enum ProductType
{
Material,
Course,
Service,
Link,
Other
}
public enum OrderStatus
{
Pending,
Paid,
Failed,
Closed,
PartiallyRefunded,
Refunded
}
public enum PaymentStatus
{
Pending,
Paid,
Failed,
Cancelled,
PartiallyRefunded,
Refunded
}
public enum EntitlementScopeType
{
Tenant,
Region,
Module,
Subject,
QuestionBank
}
public enum EntitlementStatus
{
Active,
Revoked,
Expired
}
public enum DiscountType
{
Percent,
Fixed
}
public enum CouponRedemptionStatus
{
Claimed,
Used,
Expired,
Cancelled
}
public enum CommerceRefundStatus
{
Requested,
Approved,
Processing,
Succeeded,
Failed,
Rejected,
Cancelled
}
public enum RefundEntitlementAction
{
None,
RevokeOnSuccess
}
public enum ReconciliationBillType
{
Payment,
Refund,
Combined
}
public enum ReconciliationSource
{
ManualUpload,
ProviderDownload,
Api,
Worker
}
public enum ReconciliationBatchStatus
{
Preview,
Pending,
Processing,
Completed,
CompletedWithIssues,
Failed
}
public enum ReconciliationTransactionType
{
Payment,
Refund
}
public enum ReconciliationMatchStatus
{
Matched,
AmountMismatch,
StatusMismatch,
MissingLocal,
MissingProvider,
Duplicate,
Ignored
}
public enum ReconciliationIssueMatchStatus
{
AmountMismatch,
StatusMismatch,
MissingLocal,
MissingProvider,
Duplicate
}
public enum NotificationSeverity
{
Info,
Warning,
Error,
Critical
}
public enum ReconciliationIssueStatus
{
Open,
Investigating,
Resolved,
Ignored,
Escalated
}
public enum ReconciliationResolutionType
{
None,
ProviderConfirmed,
LocalCorrected,
ManualAdjustment,
FalsePositive,
Duplicate,
WriteOff
}
public enum CommerceAdjustmentVoucherStatus
{
Draft,
PendingReview,
Approved,
Rejected,
Closed,
Void
}
public enum CommerceAdjustmentDirection
{
IncreaseRevenue,
DecreaseRevenue,
IncreaseRefund,
DecreaseRefund,
WriteOff
}