feat: 后台手动新增租户并直接入驻接口

This commit is contained in:
2025-12-15 12:16:17 +08:00
parent 5e7f7144ed
commit 13821f2d19
3 changed files with 548 additions and 0 deletions

View File

@@ -0,0 +1,264 @@
using MediatR;
using System.ComponentModel.DataAnnotations;
using TakeoutSaaS.Application.App.Tenants.Dto;
using TakeoutSaaS.Domain.Tenants.Enums;
namespace TakeoutSaaS.Application.App.Tenants.Commands;
/// <summary>
/// 后台手动新增租户并直接入驻(创建租户 + 认证 + 订阅 + 管理员账号)。
/// </summary>
public sealed record CreateTenantManuallyCommand : IRequest<TenantDetailDto>
{
/// <summary>
/// 租户短编码,作为跨系统引用的唯一标识。
/// </summary>
[Required]
[StringLength(64)]
public string Code { get; init; } = string.Empty;
/// <summary>
/// 租户全称或品牌名称。
/// </summary>
[Required]
[StringLength(128)]
public string Name { get; init; } = string.Empty;
/// <summary>
/// 对外展示的简称。
/// </summary>
public string? ShortName { get; init; }
/// <summary>
/// 法人或公司主体名称。
/// </summary>
public string? LegalEntityName { get; init; }
/// <summary>
/// 所属行业,如餐饮、零售等。
/// </summary>
public string? Industry { get; init; }
/// <summary>
/// LOGO 图片地址。
/// </summary>
public string? LogoUrl { get; init; }
/// <summary>
/// 品牌海报或封面图。
/// </summary>
public string? CoverImageUrl { get; init; }
/// <summary>
/// 官网或主要宣传链接。
/// </summary>
public string? Website { get; init; }
/// <summary>
/// 所在国家/地区。
/// </summary>
public string? Country { get; init; }
/// <summary>
/// 所在省份或州。
/// </summary>
public string? Province { get; init; }
/// <summary>
/// 所在城市。
/// </summary>
public string? City { get; init; }
/// <summary>
/// 详细地址信息。
/// </summary>
public string? Address { get; init; }
/// <summary>
/// 主联系人姓名。
/// </summary>
public string? ContactName { get; init; }
/// <summary>
/// 主联系人电话(唯一)。
/// </summary>
public string? ContactPhone { get; init; }
/// <summary>
/// 主联系人邮箱。
/// </summary>
public string? ContactEmail { get; init; }
/// <summary>
/// 业务标签集合(逗号分隔)。
/// </summary>
public string? Tags { get; init; }
/// <summary>
/// 备注信息,用于运营记录特殊说明。
/// </summary>
public string? Remarks { get; init; }
/// <summary>
/// 最近一次暂停服务时间。
/// </summary>
public DateTime? SuspendedAt { get; init; }
/// <summary>
/// 暂停或终止的原因说明。
/// </summary>
public string? SuspensionReason { get; init; }
/// <summary>
/// 租户当前状态,默认 Active直接入驻
/// </summary>
public TenantStatus TenantStatus { get; init; } = TenantStatus.Active;
/// <summary>
/// 购买套餐 ID。
/// </summary>
[Required]
public long TenantPackageId { get; init; }
/// <summary>
/// 订阅时长(月)。
/// </summary>
[Range(1, int.MaxValue)]
public int DurationMonths { get; init; } = 12;
/// <summary>
/// 是否自动续费。
/// </summary>
public bool AutoRenew { get; init; } = false;
/// <summary>
/// 订阅生效时间UTC为空则立即生效。
/// </summary>
public DateTime? SubscriptionEffectiveFrom { get; init; }
/// <summary>
/// 下次计费时间UTC为空则默认等于到期时间。
/// </summary>
public DateTime? NextBillingDate { get; init; }
/// <summary>
/// 订阅状态,默认 Active。
/// </summary>
public SubscriptionStatus SubscriptionStatus { get; init; } = SubscriptionStatus.Active;
/// <summary>
/// 预定下次切换的套餐 ID。
/// </summary>
public long? ScheduledPackageId { get; init; }
/// <summary>
/// 订阅备注。
/// </summary>
public string? SubscriptionNotes { get; init; }
/// <summary>
/// 实名状态,默认 Approved直接通过
/// </summary>
public TenantVerificationStatus VerificationStatus { get; init; } = TenantVerificationStatus.Approved;
/// <summary>
/// 营业执照编号。
/// </summary>
public string? BusinessLicenseNumber { get; init; }
/// <summary>
/// 营业执照扫描件地址。
/// </summary>
public string? BusinessLicenseUrl { get; init; }
/// <summary>
/// 法人姓名。
/// </summary>
public string? LegalPersonName { get; init; }
/// <summary>
/// 法人身份证号。
/// </summary>
public string? LegalPersonIdNumber { get; init; }
/// <summary>
/// 法人身份证人像面图片地址。
/// </summary>
public string? LegalPersonIdFrontUrl { get; init; }
/// <summary>
/// 法人身份证国徽面图片地址。
/// </summary>
public string? LegalPersonIdBackUrl { get; init; }
/// <summary>
/// 对公账户户名。
/// </summary>
public string? BankAccountName { get; init; }
/// <summary>
/// 对公银行账号。
/// </summary>
public string? BankAccountNumber { get; init; }
/// <summary>
/// 开户行名称。
/// </summary>
public string? BankName { get; init; }
/// <summary>
/// 其他补充资料 JSON。
/// </summary>
public string? AdditionalDataJson { get; init; }
/// <summary>
/// 提交时间UTC为空则默认当前时间。
/// </summary>
public DateTime? SubmittedAt { get; init; }
/// <summary>
/// 审核时间UTC为空则默认当前时间。
/// </summary>
public DateTime? ReviewedAt { get; init; }
/// <summary>
/// 审核人姓名(展示用),为空则默认当前用户。
/// </summary>
public string? ReviewedByName { get; init; }
/// <summary>
/// 审核备注。
/// </summary>
public string? ReviewRemarks { get; init; }
/// <summary>
/// 租户管理员账号。
/// </summary>
[Required]
[StringLength(128)]
public string AdminAccount { get; init; } = string.Empty;
/// <summary>
/// 租户管理员显示名。
/// </summary>
[Required]
[StringLength(128)]
public string AdminDisplayName { get; init; } = string.Empty;
/// <summary>
/// 管理员初始密码(明文,仅用于创建时生成哈希,不会被持久化回传)。
/// </summary>
[Required]
[StringLength(128, MinimumLength = 6)]
public string AdminPassword { get; init; } = string.Empty;
/// <summary>
/// 管理员头像。
/// </summary>
public string? AdminAvatar { get; init; }
/// <summary>
/// 关联商户 ID若有
/// </summary>
public long? AdminMerchantId { get; init; }
}