using System.ComponentModel.DataAnnotations; using System.Text.Json; using Tiku.Application.Commerce; using Tiku.Domain.Commerce; using Tiku.Domain.Common; using Tiku.Domain.Tenancy; namespace Tiku.Api.Contracts; /// /// 租户交易查询参数。 /// public sealed class TenantCommerceQueryDto { /// /// 服务提供方。 /// [StringLength(50)] public string? Provider { get; set; } /// /// 状态。 /// [StringLength(32)] public string? Status { get; set; } /// /// 返回数量上限。 /// [Range(1, 200)] public int? Limit { get; set; } /// /// 用户 ID。 /// public Guid? UserId { get; set; } /// /// 地区 ID。 /// public Guid? RegionId { get; set; } } /// /// 新增或更新支付账号请求 DTO。 /// public sealed class UpsertPaymentAccountDto { /// /// 服务提供方。 /// [Required] [StringLength(50)] public string Provider { get; set; } = string.Empty; /// /// 模式。 /// [StringLength(50)] public string? Mode { get; set; } = "TenantCollect"; /// /// 显示名称。 /// [StringLength(200)] public string? DisplayName { get; set; } /// /// 状态。 /// public TenantExternalProviderStatus Status { get; set; } = TenantExternalProviderStatus.Disabled; /// /// 密钥引用。 /// [StringLength(300)] public string? SecretRef { get; set; } /// /// 优先级。 /// public int? Priority { get; set; } /// /// 公开配置内容。 /// public JsonElement ConfigPublic { get; set; } = JsonDefaults.Object(); public UpsertPaymentAccountCommand ToCommand() { return new UpsertPaymentAccountCommand(Provider, Mode, DisplayName, Status, SecretRef, Priority, ConfigPublic); } } /// /// 新增或更新租户Secret请求 DTO。 /// public sealed class UpsertTenantSecretDto { /// /// 用途。 /// [Required] [StringLength(80)] public string Purpose { get; set; } = "payment"; /// /// 服务提供方。 /// [Required] [StringLength(50)] public string Provider { get; set; } = string.Empty; /// /// 密钥键。 /// [Required] [StringLength(120)] public string SecretKey { get; set; } = string.Empty; /// /// 密钥引用。 /// [StringLength(300)] public string SecretRef { get; set; } = string.Empty; /// /// 状态。 /// public TenantSecretStatus Status { get; set; } = TenantSecretStatus.Active; /// /// 密钥载荷。 /// public JsonElement SecretPayload { get; set; } = JsonDefaults.Object(); /// /// 过期时间。 /// public DateTimeOffset? ExpiresAt { get; set; } public UpsertTenantSecretCommand ToCommand() { return new UpsertTenantSecretCommand( Purpose, Provider, SecretKey, SecretRef, Status, SecretPayload, ExpiresAt); } } /// /// 创建编码批次请求 DTO。 /// public sealed class CreateCodeBatchDto { /// /// 名称。 /// [Required] [StringLength(200)] public string Name { get; set; } = string.Empty; /// /// 总数量。 /// [Range(1, 1000)] public int TotalCount { get; set; } /// /// 天数。 /// [Range(1, 3650)] public int Days { get; set; } /// /// 地区 ID。 /// public Guid? RegionId { get; set; } /// /// 售卖类型。 /// [StringLength(50)] public string? SaleType { get; set; } /// /// 渠道。 /// [StringLength(100)] public string? Channel { get; set; } /// /// 默认单价,单位为分。 /// [Range(0, int.MaxValue)] public int? DefaultUnitPriceCents { get; set; } /// /// 成本价,单位为分。 /// [Range(0, int.MaxValue)] public int? CostPriceCents { get; set; } /// /// 备注。 /// [StringLength(1000)] public string? Remark { get; set; } public CreateCodeBatchCommand ToCommand() { return new CreateCodeBatchCommand( Name, TotalCount, Days, RegionId, SaleType, Channel, DefaultUnitPriceCents, CostPriceCents, Remark); } } /// /// 核销激活码编码请求 DTO。 /// public sealed class RedeemActivationCodeDto { /// /// 编码。 /// [Required] [StringLength(100)] public string Code { get; set; } = string.Empty; /// /// 用户 ID。 /// [Required] public Guid UserId { get; set; } /// /// 地区 ID。 /// public Guid? RegionId { get; set; } public RedeemActivationCodeCommand ToCommand() { return new RedeemActivationCodeCommand(Code, UserId, RegionId); } } /// /// 新增或更新积分任务请求 DTO。 /// public sealed class UpsertPointTaskDto { /// /// ID。 /// public Guid? Id { get; set; } /// /// 任务键。 /// [Required] [StringLength(100)] public string TaskKey { get; set; } = string.Empty; /// /// 标题。 /// [Required] [StringLength(200)] public string Title { get; set; } = string.Empty; /// /// 说明。 /// [StringLength(1000)] public string? Description { get; set; } /// /// 任务类型。 /// public PointActivityTaskType TaskType { get; set; } = PointActivityTaskType.Manual; /// /// 状态。 /// public PointActivityTaskStatus Status { get; set; } = PointActivityTaskStatus.Active; /// /// 积分数量。 /// [Range(1, int.MaxValue)] public int Points { get; set; } /// /// 每用户最多领取次数。 /// [Range(1, 1000)] public int MaxClaimsPerUser { get; set; } = 1; /// /// 开始时间。 /// public DateTimeOffset? StartsAt { get; set; } /// /// 结束时间。 /// public DateTimeOffset? EndsAt { get; set; } /// /// 排序值。 /// public int SortOrder { get; set; } /// /// 规则配置。 /// public JsonElement Rules { get; set; } = JsonDefaults.Object(); /// /// 扩展元数据。 /// public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public UpsertPointTaskCommand ToCommand() { return new UpsertPointTaskCommand( Id, TaskKey, Title, Description, TaskType, Status, Points, MaxClaimsPerUser, StartsAt, EndsAt, SortOrder, Rules, Metadata); } } /// /// 新增或更新积分兑换Item请求 DTO。 /// public sealed class UpsertPointExchangeItemDto { /// /// ID。 /// public Guid? Id { get; set; } /// /// 地区 ID。 /// public Guid? RegionId { get; set; } /// /// 兑换项键。 /// [Required] [StringLength(100)] public string ItemKey { get; set; } = string.Empty; /// /// 名称。 /// [Required] [StringLength(200)] public string Name { get; set; } = string.Empty; /// /// 说明。 /// [StringLength(1000)] public string? Description { get; set; } /// /// 兑换项类型。 /// public PointExchangeItemType ItemType { get; set; } = PointExchangeItemType.Entitlement; /// /// 状态。 /// public PointExchangeItemStatus Status { get; set; } = PointExchangeItemStatus.Active; /// /// 所需积分。 /// [Range(1, int.MaxValue)] public int PointsCost { get; set; } /// /// 库存数量。 /// [Range(0, int.MaxValue)] public int? Stock { get; set; } /// /// 天数。 /// [Range(0, 3650)] public int? Days { get; set; } /// /// 排序值。 /// public int SortOrder { get; set; } /// /// 开始时间。 /// public DateTimeOffset? StartsAt { get; set; } /// /// 结束时间。 /// public DateTimeOffset? EndsAt { get; set; } /// /// 履约载荷。 /// public JsonElement FulfillmentPayload { get; set; } = JsonDefaults.Object(); /// /// 扩展元数据。 /// public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public UpsertPointExchangeItemCommand ToCommand() { return new UpsertPointExchangeItemCommand( Id, RegionId, ItemKey, Name, Description, ItemType, Status, PointsCost, Stock, Days, SortOrder, StartsAt, EndsAt, FulfillmentPayload, Metadata); } } /// /// 创建退款Request请求 DTO。 /// public sealed class CreateRefundRequestDto { /// /// 订单 ID。 /// [Required] public Guid OrderId { get; set; } /// /// 支付记录 ID。 /// public Guid? PaymentId { get; set; } /// /// 金额,单位为分。 /// [Range(1, int.MaxValue)] public int AmountCents { get; set; } /// /// 原因。 /// [StringLength(1000)] public string? Reason { get; set; } /// /// 权益动作。 /// public RefundEntitlementAction EntitlementAction { get; set; } = RefundEntitlementAction.RevokeOnSuccess; /// /// 扩展元数据。 /// public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public CreateRefundRequestCommand ToCommand() { return new CreateRefundRequestCommand(OrderId, PaymentId, AmountCents, Reason, EntitlementAction, Metadata); } } /// /// 更新退款状态请求 DTO。 /// public sealed class UpdateRefundStatusDto { /// /// 退款申请 ID。 /// [Required] public Guid RefundRequestId { get; set; } /// /// 状态。 /// public CommerceRefundStatus Status { get; set; } /// /// 原因。 /// [StringLength(1000)] public string? Reason { get; set; } /// /// 渠道退款单号。 /// [StringLength(200)] public string? ProviderRefundNo { get; set; } public UpdateRefundStatusCommand ToCommand() { return new UpdateRefundStatusCommand(RefundRequestId, Status, Reason, ProviderRefundNo); } } /// /// 创建对账批次请求 DTO。 /// public sealed class CreateReconciliationBatchDto { /// /// 服务提供方。 /// [Required] [StringLength(50)] 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; /// /// 来源名称。 /// [StringLength(200)] public string? SourceName { get; set; } /// /// 来源哈希。 /// [Required] [StringLength(200)] public string SourceHash { get; set; } = string.Empty; /// /// 扩展元数据。 /// public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public CreateReconciliationBatchCommand ToCommand() { return new CreateReconciliationBatchCommand(Provider, BillDate, BillType, Source, SourceName, SourceHash, Metadata); } } /// /// 更新对账Issue请求 DTO。 /// public sealed class UpdateReconciliationIssueDto { /// /// 工单 ID。 /// [Required] public Guid IssueId { get; set; } /// /// 状态。 /// public ReconciliationIssueStatus Status { get; set; } = ReconciliationIssueStatus.Investigating; /// /// 处理类型。 /// public ReconciliationResolutionType ResolutionType { get; set; } = ReconciliationResolutionType.None; /// /// 备注。 /// [StringLength(1000)] public string? Note { get; set; } /// /// 分配处理人。 /// public Guid? AssignedTo { get; set; } public UpdateReconciliationIssueCommand ToCommand() { return new UpdateReconciliationIssueCommand(IssueId, Status, ResolutionType, Note, AssignedTo); } } /// /// 预览对账导入请求 DTO。 /// public sealed class PreviewReconciliationImportDto { /// /// 服务提供方。 /// [Required] [StringLength(50)] public string Provider { get; set; } = string.Empty; /// /// 账单日期。 /// public DateOnly BillDate { get; set; } /// /// 账单类型。 /// public ReconciliationBillType BillType { get; set; } = ReconciliationBillType.Combined; /// /// 来源名称。 /// [Required] [StringLength(300)] public string SourceName { get; set; } = string.Empty; /// /// 数据行列表。 /// public JsonElement Rows { get; set; } = JsonDefaults.Array(); public PreviewReconciliationImportCommand ToPreviewCommand() => new(Provider, BillDate, BillType, SourceName, Rows); public ImportReconciliationCommand ToImportCommand() => new(Provider, BillDate, BillType, SourceName, Rows); } /// /// 创建调账凭证请求 DTO。 /// public sealed class CreateAdjustmentVoucherDto { /// /// 工单 ID。 /// public Guid? IssueId { get; set; } /// /// 批次 ID。 /// public Guid? BatchId { get; set; } /// /// 兑换项 ID。 /// public Guid? ItemId { get; set; } /// /// 订单 ID。 /// public Guid? OrderId { get; set; } /// /// 支付记录 ID。 /// public Guid? PaymentId { get; set; } /// /// 退款申请 ID。 /// public Guid? RefundRequestId { get; set; } /// /// 方向。 /// public CommerceAdjustmentDirection Direction { get; set; } = CommerceAdjustmentDirection.IncreaseRevenue; /// /// 金额,单位为分。 /// [Range(1, int.MaxValue)] public int AmountCents { get; set; } /// /// 币种。 /// [StringLength(10)] public string? Currency { get; set; } /// /// 原因。 /// [Required] [StringLength(1000)] public string Reason { get; set; } = string.Empty; /// /// 证明资产键。 /// [StringLength(500)] public string? ProofAssetKey { get; set; } /// /// 扩展元数据。 /// public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public CreateAdjustmentVoucherCommand ToCommand() => new( IssueId, BatchId, ItemId, OrderId, PaymentId, RefundRequestId, Direction, AmountCents, Currency, Reason, ProofAssetKey, Metadata); } /// /// 更新调账凭证状态请求 DTO。 /// public sealed class UpdateAdjustmentVoucherStatusDto { /// /// 凭证 ID。 /// [Required] public Guid VoucherId { get; set; } /// /// 状态。 /// public CommerceAdjustmentVoucherStatus Status { get; set; } = CommerceAdjustmentVoucherStatus.PendingReview; /// /// 备注。 /// [StringLength(1000)] public string? Note { get; set; } public UpdateAdjustmentVoucherStatusCommand ToCommand() => new(VoucherId, Status, Note); } /// /// RequestProviderBill任务请求 DTO。 /// public sealed class RequestProviderBillJobDto { /// /// 服务提供方。 /// [Required] [StringLength(50)] public string Provider { get; set; } = string.Empty; /// /// 账单日期。 /// public DateOnly BillDate { get; set; } /// /// 账单类型。 /// public ReconciliationBillType BillType { get; set; } = ReconciliationBillType.Combined; /// /// 计划运行时间。 /// public DateTimeOffset? RunAfter { get; set; } public RequestProviderBillJobCommand ToCommand() => new(Provider, BillDate, BillType, RunAfter); } /// /// 退款通知请求 DTO。 /// public sealed class RefundNotificationDto { /// /// 退款单号。 /// [Required] [StringLength(100)] public string RefundNo { get; set; } = string.Empty; /// /// 渠道退款单号。 /// [StringLength(200)] public string? ProviderRefundNo { get; set; } /// /// 状态。 /// public CommerceRefundStatus Status { get; set; } = CommerceRefundStatus.Succeeded; /// /// 事件 ID。 /// [StringLength(200)] public string? EventId { get; set; } /// /// 任务载荷。 /// public JsonElement Payload { get; set; } = JsonDefaults.Object(); public RefundNotificationCommand ToCommand(string provider) => new(provider, RefundNo, ProviderRefundNo, Status, EventId, Payload); } /// /// 更新积分兑换订单状态请求 DTO。 /// public sealed class UpdatePointExchangeOrderStatusDto { /// /// 订单 ID。 /// [Required] public Guid OrderId { get; set; } /// /// 状态。 /// public PointExchangeOrderStatus Status { get; set; } public UpdatePointExchangeOrderStatusCommand ToCommand() { return new UpdatePointExchangeOrderStatusCommand(OrderId, Status); } } /// /// 新增或更新租户优惠券请求 DTO。 /// public sealed class UpsertTenantCouponDto { /// /// ID。 /// public Guid? Id { get; set; } /// /// 编码。 /// [Required] [StringLength(100)] public string Code { get; set; } = string.Empty; /// /// 套餐 ID。 /// public Guid? PlanId { get; set; } /// /// 优惠类型。 /// public DiscountType DiscountType { get; set; } = DiscountType.Fixed; /// /// 优惠值。 /// [Range(typeof(decimal), "0.01", "999999")] public decimal DiscountValue { get; set; } /// /// 有效期开始时间。 /// public DateTimeOffset? ValidFrom { get; set; } /// /// 有效期结束时间。 /// public DateTimeOffset? ValidTo { get; set; } /// /// 最大使用次数。 /// [Range(1, int.MaxValue)] public int? MaxUses { get; set; } /// /// 来源。 /// [StringLength(50)] public string? Source { get; set; } /// /// 备注。 /// [StringLength(1000)] public string? Remark { get; set; } public UpsertCouponCommand ToCommand() { return new UpsertCouponCommand( Id, Code, PlanId, DiscountType, DiscountValue, ValidFrom, ValidTo, MaxUses, Source, Remark); } }