using System.ComponentModel.DataAnnotations; using System.Text.Json; using Tiku.Application.PlatformAdmin; using Tiku.Domain.Common; using Tiku.Domain.Commerce; using Tiku.Domain.Identity; using Tiku.Domain.Platform; using Tiku.Domain.Tenancy; namespace Tiku.Api.Contracts; /// /// 平台管理端查询参数。 /// public sealed class PlatformAdminQueryDto { /// /// 状态。 /// [StringLength(32)] public string? Status { get; set; } /// /// 搜索关键字。 /// [StringLength(200)] public string? Search { get; set; } /// /// 返回数量上限。 /// [Range(1, 200)] public int? Limit { get; set; } public PlatformAdminQuery ToQuery() => new(Status, Search, Limit); } /// /// 创建平台租户请求 DTO。 /// public sealed class CreatePlatformTenantDto { /// /// 短编码。 /// [Required] [StringLength(100)] public string Slug { get; set; } = string.Empty; /// /// 名称。 /// [Required] [StringLength(200)] public string Name { get; set; } = string.Empty; /// /// 法定名称。 /// [StringLength(300)] public string? LegalName { get; set; } /// /// 状态。 /// public TenantStatus Status { get; set; } = TenantStatus.Active; /// /// 账务状态。 /// public BillingStatus BillingStatus { get; set; } = BillingStatus.Trial; /// /// 扩展元数据。 /// public JsonElement Metadata { get; set; } = JsonDefaults.Object(); /// /// 租户负责人邮箱。 /// [EmailAddress, StringLength(320)] public string? OwnerEmail { get; set; } /// /// 租户负责人手机号。 /// [Phone, StringLength(32)] public string? OwnerPhone { get; set; } /// /// 租户负责人姓名。 /// [Required, StringLength(100)] public string OwnerName { get; set; } = string.Empty; /// /// 临时密码。 /// [Required, StringLength(200, MinimumLength = 12)] public string TemporaryPassword { get; set; } = string.Empty; public CreatePlatformTenantCommand ToCommand() => new( Slug, Name, LegalName, Status, BillingStatus, Metadata, OwnerEmail, OwnerPhone, OwnerName, TemporaryPassword); } /// /// 更新平台租户状态请求 DTO。 /// public sealed class UpdatePlatformTenantStatusDto { /// /// 租户 ID。 /// [Required] public Guid TenantId { get; set; } /// /// 状态。 /// public TenantStatus Status { get; set; } = TenantStatus.Active; /// /// 账务状态。 /// public BillingStatus BillingStatus { get; set; } = BillingStatus.Active; /// /// 原因。 /// [StringLength(1000)] public string? Reason { get; set; } public UpdatePlatformTenantStatusCommand ToCommand() => new(TenantId, Status, BillingStatus, Reason); } /// /// 新增或更新平台租户账务资料请求 DTO。 /// public sealed class UpsertPlatformTenantBillingProfileDto { /// /// 租户 ID。 /// [Required] public Guid TenantId { get; set; } /// /// 账务名称。 /// [StringLength(300)] public string? BillingName { get; set; } /// /// 税号。 /// [StringLength(100)] public string? TaxId { get; set; } /// /// 联系人姓名。 /// [StringLength(100)] public string? ContactName { get; set; } /// /// 联系人手机号。 /// [StringLength(32)] public string? ContactPhone { get; set; } /// /// 联系人邮箱。 /// [StringLength(320)] public string? ContactEmail { get; set; } /// /// 账务地址。 /// [StringLength(1000)] public string? BillingAddress { get; set; } /// /// 发票抬头。 /// [StringLength(300)] public string? InvoiceTitle { get; set; } /// /// 发票类型。 /// public TenantBillingInvoiceTitleType? InvoiceType { get; set; } /// /// 开户银行。 /// [StringLength(300)] public string? BankName { get; set; } /// /// 脱敏银行账号。 /// [StringLength(100)] public string? BankAccountMasked { get; set; } /// /// 扩展元数据。 /// public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public UpsertPlatformTenantBillingProfileCommand ToCommand() => new( TenantId, BillingName, TaxId, ContactName, ContactPhone, ContactEmail, BillingAddress, InvoiceTitle, InvoiceType, BankName, BankAccountMasked, Metadata); } /// /// 新增或更新平台Staff请求 DTO。 /// public sealed class UpsertPlatformStaffDto { /// /// 用户 ID。 /// public Guid? UserId { get; set; } /// /// 邮箱。 /// [StringLength(320)] public string? Email { get; set; } /// /// 手机号。 /// [StringLength(32)] public string? Phone { get; set; } /// /// 名称。 /// [StringLength(200)] public string? Name { get; set; } /// /// 状态。 /// public UserStatus Status { get; set; } = UserStatus.Active; /// /// 角色 ID 列表。 /// public IReadOnlyCollection RoleIds { get; set; } = []; public UpsertPlatformStaffCommand ToCommand() => new(UserId, Email, Phone, Name, Status, RoleIds); } /// /// 更新平台Staff状态请求 DTO。 /// public sealed class UpdatePlatformStaffStatusDto { /// /// 用户 ID。 /// [Required] public Guid UserId { get; set; } /// /// 状态。 /// public UserStatus Status { get; set; } = UserStatus.Active; /// /// 原因。 /// [StringLength(1000)] public string? Reason { get; set; } public UpdatePlatformStaffStatusCommand ToCommand() => new(UserId, Status, Reason); } /// /// 更新平台审计Alert状态请求 DTO。 /// public sealed class UpdatePlatformAuditAlertStatusDto { /// /// 告警 ID。 /// [Required] public Guid AlertId { get; set; } /// /// 状态。 /// public PlatformAuditAlertStatus Status { get; set; } = PlatformAuditAlertStatus.Acknowledged; /// /// 处理备注。 /// [StringLength(1000)] public string? ResolutionNote { get; set; } public UpdatePlatformAuditAlertStatusCommand ToCommand() => new(AlertId, Status, ResolutionNote); } /// /// 新增或更新平台DunningChannel请求 DTO。 /// public sealed class UpsertPlatformBillingDunningChannelDto { /// /// 通知渠道 ID。 /// public Guid? ChannelId { get; set; } /// /// 渠道编码。 /// [Required] [StringLength(100)] public string ChannelCode { get; set; } = string.Empty; /// /// 名称。 /// [Required] [StringLength(200)] public string Name { get; set; } = string.Empty; /// /// 说明。 /// [StringLength(1000)] public string? Description { get; set; } /// /// 是否启用。 /// public bool Enabled { get; set; } = true; /// /// 服务提供方。 /// public PlatformBillingDunningProvider Provider { get; set; } = PlatformBillingDunningProvider.Generic; /// /// Webhook 地址。 /// [Required] [StringLength(2048)] public string WebhookUrl { get; set; } = string.Empty; /// /// 密钥引用。 /// [StringLength(300)] public string? SecretRef { get; set; } /// /// 提醒类型列表。 /// public IReadOnlyCollection ReminderTypes { get; set; } = ["overdue", "final_notice"]; /// /// 提醒渠道列表。 /// public IReadOnlyCollection ReminderChannels { get; set; } = ["internal"]; /// /// 最低提醒级别。 /// [Range(1, 20)] public int MinReminderLevel { get; set; } = 1; /// /// 租户 ID 列表。 /// public IReadOnlyCollection TenantIds { get; set; } = []; /// /// 超时时长,单位为秒。 /// [Range(1, 60)] public int TimeoutSeconds { get; set; } = 10; /// /// 扩展元数据。 /// public JsonElement Metadata { get; set; } = JsonDefaults.Object(); public UpsertPlatformBillingDunningChannelCommand ToCommand() => new( ChannelId, ChannelCode, Name, Description, Enabled, Provider, WebhookUrl, SecretRef, ReminderTypes, ReminderChannels, MinReminderLevel, TenantIds, TimeoutSeconds, Metadata); } /// /// 禁用平台DunningChannel请求 DTO。 /// public sealed class DisablePlatformBillingDunningChannelDto { /// /// 通知渠道 ID。 /// [Required] public Guid ChannelId { get; set; } /// /// 原因。 /// [StringLength(1000)] public string? Reason { get; set; } public DisablePlatformBillingDunningChannelCommand ToCommand() => new(ChannelId, Reason); } /// /// 重试平台Dunning事件请求 DTO。 /// public sealed class RetryPlatformBillingDunningEventDto { /// /// 事件 ID。 /// [Required] public Guid EventId { get; set; } /// /// 原因。 /// [StringLength(1000)] public string? Reason { get; set; } public RetryPlatformBillingDunningEventCommand ToCommand() => new(EventId, Reason); }