diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/ChangeTenantSubscriptionPlanCommand.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/ChangeTenantSubscriptionPlanCommand.cs index d9c6287..5c052be 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/ChangeTenantSubscriptionPlanCommand.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/ChangeTenantSubscriptionPlanCommand.cs @@ -7,9 +7,33 @@ namespace TakeoutSaaS.Application.App.Tenants.Commands; /// /// 套餐升降配命令。 /// -public sealed record ChangeTenantSubscriptionPlanCommand( - [property: Required] long TenantId, - [property: Required] long TenantSubscriptionId, - [property: Required] long TargetPackageId, - bool Immediate, - string? Notes) : IRequest; +public sealed record ChangeTenantSubscriptionPlanCommand : IRequest +{ + /// + /// 租户 ID(雪花算法)。 + /// + [Required] + public long TenantId { get; init; } + + /// + /// 现有订阅 ID。 + /// + [Required] + public long TenantSubscriptionId { get; init; } + + /// + /// 目标套餐 ID。 + /// + [Required] + public long TargetPackageId { get; init; } + + /// + /// 是否立即生效,否则在下一结算周期生效。 + /// + public bool Immediate { get; init; } + + /// + /// 调整备注。 + /// + public string? Notes { get; init; } +} diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/CreateTenantAnnouncementCommand.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/CreateTenantAnnouncementCommand.cs index da68b6f..dd6735a 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/CreateTenantAnnouncementCommand.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/CreateTenantAnnouncementCommand.cs @@ -9,12 +9,43 @@ namespace TakeoutSaaS.Application.App.Tenants.Commands; /// public sealed record CreateTenantAnnouncementCommand : IRequest { + /// + /// 租户 ID(雪花算法)。 + /// public long TenantId { get; init; } + + /// + /// 公告标题。 + /// public string Title { get; init; } = string.Empty; + + /// + /// 公告正文内容。 + /// public string Content { get; init; } = string.Empty; + + /// + /// 公告类型。 + /// public TenantAnnouncementType AnnouncementType { get; init; } = TenantAnnouncementType.System; + + /// + /// 优先级,数值越大越靠前。 + /// public int Priority { get; init; } = 0; + + /// + /// 生效开始时间(UTC)。 + /// public DateTime EffectiveFrom { get; init; } = DateTime.UtcNow; + + /// + /// 生效结束时间(UTC),为空则长期有效。 + /// public DateTime? EffectiveTo { get; init; } + + /// + /// 是否启用。 + /// public bool IsActive { get; init; } = true; } diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/CreateTenantBillingCommand.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/CreateTenantBillingCommand.cs index 16c771d..1bc64a7 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/CreateTenantBillingCommand.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/CreateTenantBillingCommand.cs @@ -9,13 +9,48 @@ namespace TakeoutSaaS.Application.App.Tenants.Commands; /// public sealed record CreateTenantBillingCommand : IRequest { + /// + /// 租户 ID(雪花算法)。 + /// public long TenantId { get; init; } + + /// + /// 账单编号。 + /// public string StatementNo { get; init; } = string.Empty; + + /// + /// 计费周期开始时间(UTC)。 + /// public DateTime PeriodStart { get; init; } + + /// + /// 计费周期结束时间(UTC)。 + /// public DateTime PeriodEnd { get; init; } + + /// + /// 应付金额。 + /// public decimal AmountDue { get; init; } + + /// + /// 已付金额。 + /// public decimal AmountPaid { get; init; } + + /// + /// 账单状态。 + /// public TenantBillingStatus Status { get; init; } = TenantBillingStatus.Pending; + + /// + /// 到期日(UTC)。 + /// public DateTime DueDate { get; init; } + + /// + /// 账单明细 JSON。 + /// public string? LineItemsJson { get; init; } } diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/CreateTenantSubscriptionCommand.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/CreateTenantSubscriptionCommand.cs index 468ace2..b31a92d 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/CreateTenantSubscriptionCommand.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/CreateTenantSubscriptionCommand.cs @@ -7,9 +7,32 @@ namespace TakeoutSaaS.Application.App.Tenants.Commands; /// /// 新建或续费订阅。 /// -public sealed record CreateTenantSubscriptionCommand( - [property: Required] long TenantId, - [property: Required] long TenantPackageId, - int DurationMonths, - bool AutoRenew, - string? Notes) : IRequest; +public sealed record CreateTenantSubscriptionCommand : IRequest +{ + /// + /// 租户 ID(雪花算法)。 + /// + [Required] + public long TenantId { get; init; } + + /// + /// 套餐 ID。 + /// + [Required] + public long TenantPackageId { get; init; } + + /// + /// 订阅时长(月)。 + /// + public int DurationMonths { get; init; } + + /// + /// 是否自动续费。 + /// + public bool AutoRenew { get; init; } + + /// + /// 备注信息。 + /// + public string? Notes { get; init; } +} diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/DeleteTenantAnnouncementCommand.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/DeleteTenantAnnouncementCommand.cs index c67877c..3cd5964 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/DeleteTenantAnnouncementCommand.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/DeleteTenantAnnouncementCommand.cs @@ -7,6 +7,13 @@ namespace TakeoutSaaS.Application.App.Tenants.Commands; /// public sealed record DeleteTenantAnnouncementCommand : IRequest { + /// + /// 租户 ID(雪花算法)。 + /// public long TenantId { get; init; } + + /// + /// 公告 ID。 + /// public long AnnouncementId { get; init; } } diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/MarkTenantAnnouncementReadCommand.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/MarkTenantAnnouncementReadCommand.cs index 85c679a..97ce6e1 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/MarkTenantAnnouncementReadCommand.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/MarkTenantAnnouncementReadCommand.cs @@ -8,6 +8,13 @@ namespace TakeoutSaaS.Application.App.Tenants.Commands; /// public sealed record MarkTenantAnnouncementReadCommand : IRequest { + /// + /// 租户 ID(雪花算法)。 + /// public long TenantId { get; init; } + + /// + /// 公告 ID。 + /// public long AnnouncementId { get; init; } } diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/MarkTenantBillingPaidCommand.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/MarkTenantBillingPaidCommand.cs index 5479882..e2c9f18 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/MarkTenantBillingPaidCommand.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/MarkTenantBillingPaidCommand.cs @@ -8,8 +8,23 @@ namespace TakeoutSaaS.Application.App.Tenants.Commands; /// public sealed record MarkTenantBillingPaidCommand : IRequest { + /// + /// 租户 ID(雪花算法)。 + /// public long TenantId { get; init; } + + /// + /// 账单 ID。 + /// public long BillingId { get; init; } + + /// + /// 本次支付金额。 + /// public decimal AmountPaid { get; init; } + + /// + /// 支付时间(UTC)。 + /// public DateTime PaidAt { get; init; } = DateTime.UtcNow; } diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/MarkTenantNotificationReadCommand.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/MarkTenantNotificationReadCommand.cs index 31ddb58..149a74a 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/MarkTenantNotificationReadCommand.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/MarkTenantNotificationReadCommand.cs @@ -8,6 +8,13 @@ namespace TakeoutSaaS.Application.App.Tenants.Commands; /// public sealed record MarkTenantNotificationReadCommand : IRequest { + /// + /// 租户 ID(雪花算法)。 + /// public long TenantId { get; init; } + + /// + /// 通知 ID。 + /// public long NotificationId { get; init; } } diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/RegisterTenantCommand.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/RegisterTenantCommand.cs index 43cc053..d26a96b 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/RegisterTenantCommand.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/RegisterTenantCommand.cs @@ -7,15 +7,65 @@ namespace TakeoutSaaS.Application.App.Tenants.Commands; /// /// 注册租户命令。 /// -public sealed record RegisterTenantCommand( - [property: Required, StringLength(64)] string Code, - [property: Required, StringLength(128)] string Name, - string? ShortName, - string? Industry, - string? ContactName, - string? ContactPhone, - string? ContactEmail, - [property: Required] long TenantPackageId, - int DurationMonths = 12, - bool AutoRenew = true, - DateTime? EffectiveFrom = null) : IRequest; +public sealed record RegisterTenantCommand : IRequest +{ + /// + /// 唯一租户编码。 + /// + [Required] + [StringLength(64)] + public string Code { get; init; } = string.Empty; + + /// + /// 租户名称。 + /// + [Required] + [StringLength(128)] + public string Name { get; init; } = string.Empty; + + /// + /// 租户简称。 + /// + public string? ShortName { get; init; } + + /// + /// 行业类型。 + /// + public string? Industry { get; init; } + + /// + /// 联系人姓名。 + /// + public string? ContactName { get; init; } + + /// + /// 联系人电话。 + /// + public string? ContactPhone { get; init; } + + /// + /// 联系人邮箱。 + /// + public string? ContactEmail { get; init; } + + /// + /// 购买套餐 ID。 + /// + [Required] + public long TenantPackageId { get; init; } + + /// + /// 订阅时长(月),默认 12 个月。 + /// + public int DurationMonths { get; init; } = 12; + + /// + /// 是否自动续费。 + /// + public bool AutoRenew { get; init; } = true; + + /// + /// 生效时间(UTC),为空则立即生效。 + /// + public DateTime? EffectiveFrom { get; init; } +} diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/ReviewTenantCommand.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/ReviewTenantCommand.cs index 5784f9b..7b1c6b6 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/ReviewTenantCommand.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/ReviewTenantCommand.cs @@ -7,7 +7,21 @@ namespace TakeoutSaaS.Application.App.Tenants.Commands; /// /// 审核租户命令。 /// -public sealed record ReviewTenantCommand( - [property: Required] long TenantId, - bool Approve, - string? Reason) : IRequest; +public sealed record ReviewTenantCommand : IRequest +{ + /// + /// 租户 ID(雪花算法)。 + /// + [Required] + public long TenantId { get; init; } + + /// + /// 是否通过审核。 + /// + public bool Approve { get; init; } + + /// + /// 审核备注或拒绝原因。 + /// + public string? Reason { get; init; } +} diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/SubmitTenantVerificationCommand.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/SubmitTenantVerificationCommand.cs index 8a94a46..94de46d 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/SubmitTenantVerificationCommand.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/SubmitTenantVerificationCommand.cs @@ -7,15 +7,61 @@ namespace TakeoutSaaS.Application.App.Tenants.Commands; /// /// 提交租户实名认证资料。 /// -public sealed record SubmitTenantVerificationCommand( - [property: Required] long TenantId, - string? BusinessLicenseNumber, - string? BusinessLicenseUrl, - string? LegalPersonName, - string? LegalPersonIdNumber, - string? LegalPersonIdFrontUrl, - string? LegalPersonIdBackUrl, - string? BankAccountName, - string? BankAccountNumber, - string? BankName, - string? AdditionalDataJson) : IRequest; +public sealed record SubmitTenantVerificationCommand : IRequest +{ + /// + /// 租户 ID(雪花算法)。 + /// + [Required] + public long TenantId { get; init; } + + /// + /// 营业执照编号。 + /// + public string? BusinessLicenseNumber { get; init; } + + /// + /// 营业执照扫描件地址。 + /// + public string? BusinessLicenseUrl { get; init; } + + /// + /// 法人姓名。 + /// + public string? LegalPersonName { get; init; } + + /// + /// 法人身份证号。 + /// + public string? LegalPersonIdNumber { get; init; } + + /// + /// 法人身份证人像面图片地址。 + /// + public string? LegalPersonIdFrontUrl { get; init; } + + /// + /// 法人身份证国徽面图片地址。 + /// + public string? LegalPersonIdBackUrl { get; init; } + + /// + /// 对公账户户名。 + /// + public string? BankAccountName { get; init; } + + /// + /// 对公银行账号。 + /// + public string? BankAccountNumber { get; init; } + + /// + /// 开户行名称。 + /// + public string? BankName { get; init; } + + /// + /// 其他补充资料 JSON。 + /// + public string? AdditionalDataJson { get; init; } +} diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/UpdateTenantAnnouncementCommand.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/UpdateTenantAnnouncementCommand.cs index 57c6569..b495d69 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/UpdateTenantAnnouncementCommand.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Commands/UpdateTenantAnnouncementCommand.cs @@ -9,13 +9,48 @@ namespace TakeoutSaaS.Application.App.Tenants.Commands; /// public sealed record UpdateTenantAnnouncementCommand : IRequest { + /// + /// 租户 ID(雪花算法)。 + /// public long TenantId { get; init; } + + /// + /// 公告 ID。 + /// public long AnnouncementId { get; init; } + + /// + /// 公告标题。 + /// public string Title { get; init; } = string.Empty; + + /// + /// 公告内容。 + /// public string Content { get; init; } = string.Empty; + + /// + /// 公告类型。 + /// public TenantAnnouncementType AnnouncementType { get; init; } = TenantAnnouncementType.System; + + /// + /// 优先级,数值越大越靠前。 + /// public int Priority { get; init; } = 0; + + /// + /// 生效开始时间(UTC)。 + /// public DateTime EffectiveFrom { get; init; } = DateTime.UtcNow; + + /// + /// 生效结束时间(UTC),为空则长期有效。 + /// public DateTime? EffectiveTo { get; init; } + + /// + /// 是否启用。 + /// public bool IsActive { get; init; } = true; } diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Dto/TenantAnnouncementDto.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Dto/TenantAnnouncementDto.cs index 5a0a7bf..79fbbe8 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Dto/TenantAnnouncementDto.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Dto/TenantAnnouncementDto.cs @@ -9,27 +9,60 @@ namespace TakeoutSaaS.Application.App.Tenants.Dto; /// public sealed class TenantAnnouncementDto { + /// + /// 公告 ID(雪花算法,序列化为字符串)。 + /// [JsonConverter(typeof(SnowflakeIdJsonConverter))] public long Id { get; init; } + /// + /// 租户 ID(雪花算法,序列化为字符串)。 + /// [JsonConverter(typeof(SnowflakeIdJsonConverter))] public long TenantId { get; init; } + /// + /// 公告标题。 + /// public string Title { get; init; } = string.Empty; + /// + /// 公告正文内容。 + /// public string Content { get; init; } = string.Empty; + /// + /// 公告类型。 + /// public TenantAnnouncementType AnnouncementType { get; init; } + /// + /// 优先级,数值越大越靠前。 + /// public int Priority { get; init; } + /// + /// 生效开始时间(UTC)。 + /// public DateTime EffectiveFrom { get; init; } + /// + /// 生效结束时间(UTC),为空则长期有效。 + /// public DateTime? EffectiveTo { get; init; } + /// + /// 是否启用。 + /// public bool IsActive { get; init; } + /// + /// 当前用户是否已读。 + /// public bool IsRead { get; init; } + /// + /// 已读时间(UTC)。 + /// public DateTime? ReadAt { get; init; } } diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Dto/TenantBillingDto.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Dto/TenantBillingDto.cs index d2b426b..1007224 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Dto/TenantBillingDto.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Dto/TenantBillingDto.cs @@ -9,25 +9,55 @@ namespace TakeoutSaaS.Application.App.Tenants.Dto; /// public sealed class TenantBillingDto { + /// + /// 账单 ID(雪花算法,序列化为字符串)。 + /// [JsonConverter(typeof(SnowflakeIdJsonConverter))] public long Id { get; init; } + /// + /// 租户 ID(雪花算法,序列化为字符串)。 + /// [JsonConverter(typeof(SnowflakeIdJsonConverter))] public long TenantId { get; init; } + /// + /// 账单编号。 + /// public string StatementNo { get; init; } = string.Empty; + /// + /// 计费周期开始时间(UTC)。 + /// public DateTime PeriodStart { get; init; } + /// + /// 计费周期结束时间(UTC)。 + /// public DateTime PeriodEnd { get; init; } + /// + /// 应付金额。 + /// public decimal AmountDue { get; init; } + /// + /// 已付金额。 + /// public decimal AmountPaid { get; init; } + /// + /// 账单状态。 + /// public TenantBillingStatus Status { get; init; } + /// + /// 到期日(UTC)。 + /// public DateTime DueDate { get; init; } + /// + /// 账单明细 JSON。 + /// public string? LineItemsJson { get; init; } } diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Dto/TenantNotificationDto.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Dto/TenantNotificationDto.cs index e6ab6a9..9a33244 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Dto/TenantNotificationDto.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Dto/TenantNotificationDto.cs @@ -9,23 +9,50 @@ namespace TakeoutSaaS.Application.App.Tenants.Dto; /// public sealed class TenantNotificationDto { + /// + /// 通知 ID(雪花算法,序列化为字符串)。 + /// [JsonConverter(typeof(SnowflakeIdJsonConverter))] public long Id { get; init; } + /// + /// 租户 ID(雪花算法,序列化为字符串)。 + /// [JsonConverter(typeof(SnowflakeIdJsonConverter))] public long TenantId { get; init; } + /// + /// 通知标题。 + /// public string Title { get; init; } = string.Empty; + /// + /// 通知内容。 + /// public string Message { get; init; } = string.Empty; + /// + /// 通道类型(如站内信、短信、邮件)。 + /// public TenantNotificationChannel Channel { get; init; } + /// + /// 通知等级。 + /// public TenantNotificationSeverity Severity { get; init; } + /// + /// 发送时间(UTC)。 + /// public DateTime SentAt { get; init; } + /// + /// 阅读时间(UTC)。 + /// public DateTime? ReadAt { get; init; } + /// + /// 附加元数据 JSON。 + /// public string? MetadataJson { get; init; } } diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/GetTenantAnnouncementQuery.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/GetTenantAnnouncementQuery.cs index 52bdcfb..74a28b3 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/GetTenantAnnouncementQuery.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/GetTenantAnnouncementQuery.cs @@ -8,6 +8,13 @@ namespace TakeoutSaaS.Application.App.Tenants.Queries; /// public sealed record GetTenantAnnouncementQuery : IRequest { + /// + /// 租户 ID(雪花算法)。 + /// public long TenantId { get; init; } + + /// + /// 公告 ID。 + /// public long AnnouncementId { get; init; } } diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/GetTenantBillQuery.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/GetTenantBillQuery.cs index f22eb99..a5ece15 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/GetTenantBillQuery.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/GetTenantBillQuery.cs @@ -8,6 +8,13 @@ namespace TakeoutSaaS.Application.App.Tenants.Queries; /// public sealed record GetTenantBillQuery : IRequest { + /// + /// 租户 ID(雪花算法)。 + /// public long TenantId { get; init; } + + /// + /// 账单 ID。 + /// public long BillingId { get; init; } } diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/SearchTenantAnnouncementsQuery.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/SearchTenantAnnouncementsQuery.cs index 3f059ad..140acb1 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/SearchTenantAnnouncementsQuery.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/SearchTenantAnnouncementsQuery.cs @@ -10,10 +10,33 @@ namespace TakeoutSaaS.Application.App.Tenants.Queries; /// public sealed record SearchTenantAnnouncementsQuery : IRequest> { + /// + /// 租户 ID(雪花算法)。 + /// public long TenantId { get; init; } + + /// + /// 公告类型筛选。 + /// public TenantAnnouncementType? AnnouncementType { get; init; } + + /// + /// 是否筛选启用状态。 + /// public bool? IsActive { get; init; } + + /// + /// 仅返回当前有效期内的公告。 + /// public bool? OnlyEffective { get; init; } + + /// + /// 页码(从 1 开始)。 + /// public int Page { get; init; } = 1; + + /// + /// 每页条数。 + /// public int PageSize { get; init; } = 20; } diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/SearchTenantBillsQuery.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/SearchTenantBillsQuery.cs index b8747e0..67d0103 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/SearchTenantBillsQuery.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/SearchTenantBillsQuery.cs @@ -10,10 +10,33 @@ namespace TakeoutSaaS.Application.App.Tenants.Queries; /// public sealed record SearchTenantBillsQuery : IRequest> { + /// + /// 租户 ID(雪花算法)。 + /// public long TenantId { get; init; } + + /// + /// 账单状态筛选。 + /// public TenantBillingStatus? Status { get; init; } + + /// + /// 账单起始时间(UTC)筛选。 + /// public DateTime? From { get; init; } + + /// + /// 账单结束时间(UTC)筛选。 + /// public DateTime? To { get; init; } + + /// + /// 页码(从 1 开始)。 + /// public int Page { get; init; } = 1; + + /// + /// 每页条数。 + /// public int PageSize { get; init; } = 20; } diff --git a/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/SearchTenantNotificationsQuery.cs b/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/SearchTenantNotificationsQuery.cs index 92875ff..ff5e8eb 100644 --- a/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/SearchTenantNotificationsQuery.cs +++ b/src/Application/TakeoutSaaS.Application/App/Tenants/Queries/SearchTenantNotificationsQuery.cs @@ -10,9 +10,28 @@ namespace TakeoutSaaS.Application.App.Tenants.Queries; /// public sealed record SearchTenantNotificationsQuery : IRequest> { + /// + /// 租户 ID(雪花算法)。 + /// public long TenantId { get; init; } + + /// + /// 通知等级筛选。 + /// public TenantNotificationSeverity? Severity { get; init; } + + /// + /// 仅返回未读通知。 + /// public bool? UnreadOnly { get; init; } + + /// + /// 页码(从 1 开始)。 + /// public int Page { get; init; } = 1; + + /// + /// 每页条数。 + /// public int PageSize { get; init; } = 20; } diff --git a/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantAnnouncementReadRepository.cs b/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantAnnouncementReadRepository.cs index 5265ff2..ac76bc8 100644 --- a/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantAnnouncementReadRepository.cs +++ b/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantAnnouncementReadRepository.cs @@ -10,13 +10,45 @@ namespace TakeoutSaaS.Domain.Tenants.Repositories; /// public interface ITenantAnnouncementReadRepository { + /// + /// 按公告查询已读记录。 + /// + /// 租户 ID。 + /// 公告 ID。 + /// 取消标记。 + /// 指定公告的已读列表。 Task> GetByAnnouncementAsync(long tenantId, long announcementId, CancellationToken cancellationToken = default); + /// + /// 批量按公告查询已读记录,可选按用户过滤。 + /// + /// 租户 ID。 + /// 公告 ID 集合。 + /// 用户 ID,空则不按用户筛选。 + /// 取消标记。 + /// 匹配条件的已读列表。 Task> GetByAnnouncementAsync(long tenantId, IEnumerable announcementIds, long? userId, CancellationToken cancellationToken = default); + /// + /// 查询指定用户对某公告的已读记录。 + /// + /// 租户 ID。 + /// 公告 ID。 + /// 用户 ID。 + /// 取消标记。 + /// 已读记录,未读返回 null。 Task FindAsync(long tenantId, long announcementId, long? userId, CancellationToken cancellationToken = default); + /// + /// 新增已读记录。 + /// + /// 已读实体。 + /// 取消标记。 Task AddAsync(TenantAnnouncementRead record, CancellationToken cancellationToken = default); + /// + /// 保存变更。 + /// + /// 取消标记。 Task SaveChangesAsync(CancellationToken cancellationToken = default); } diff --git a/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantAnnouncementRepository.cs b/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantAnnouncementRepository.cs index f42b041..c3e34b6 100644 --- a/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantAnnouncementRepository.cs +++ b/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantAnnouncementRepository.cs @@ -11,6 +11,15 @@ namespace TakeoutSaaS.Domain.Tenants.Repositories; /// public interface ITenantAnnouncementRepository { + /// + /// 查询公告列表,按类型、启用状态与生效时间筛选。 + /// + /// 租户 ID。 + /// 公告类型。 + /// 启用状态。 + /// 生效时间点,为空不限制。 + /// 取消标记。 + /// 公告集合。 Task> SearchAsync( long tenantId, TenantAnnouncementType? type, @@ -18,13 +27,40 @@ public interface ITenantAnnouncementRepository DateTime? effectiveAt, CancellationToken cancellationToken = default); + /// + /// 按 ID 获取公告。 + /// + /// 租户 ID。 + /// 公告 ID。 + /// 取消标记。 + /// 公告实体或 null。 Task FindByIdAsync(long tenantId, long announcementId, CancellationToken cancellationToken = default); + /// + /// 新增公告。 + /// + /// 公告实体。 + /// 取消标记。 Task AddAsync(TenantAnnouncement announcement, CancellationToken cancellationToken = default); + /// + /// 更新公告。 + /// + /// 公告实体。 + /// 取消标记。 Task UpdateAsync(TenantAnnouncement announcement, CancellationToken cancellationToken = default); + /// + /// 删除公告。 + /// + /// 租户 ID。 + /// 公告 ID。 + /// 取消标记。 Task DeleteAsync(long tenantId, long announcementId, CancellationToken cancellationToken = default); + /// + /// 保存变更。 + /// + /// 取消标记。 Task SaveChangesAsync(CancellationToken cancellationToken = default); } diff --git a/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantBillingRepository.cs b/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantBillingRepository.cs index 88d7fef..d4ddfa8 100644 --- a/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantBillingRepository.cs +++ b/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantBillingRepository.cs @@ -11,6 +11,15 @@ namespace TakeoutSaaS.Domain.Tenants.Repositories; /// public interface ITenantBillingRepository { + /// + /// 查询账单列表,按状态与时间范围筛选。 + /// + /// 租户 ID。 + /// 账单状态。 + /// 开始时间(UTC)。 + /// 结束时间(UTC)。 + /// 取消标记。 + /// 账单集合。 Task> SearchAsync( long tenantId, TenantBillingStatus? status, @@ -18,13 +27,41 @@ public interface ITenantBillingRepository DateTime? to, CancellationToken cancellationToken = default); + /// + /// 按 ID 获取账单。 + /// + /// 租户 ID。 + /// 账单 ID。 + /// 取消标记。 + /// 账单实体或 null。 Task FindByIdAsync(long tenantId, long billingId, CancellationToken cancellationToken = default); + /// + /// 按账单编号获取账单。 + /// + /// 租户 ID。 + /// 账单编号。 + /// 取消标记。 + /// 账单实体或 null。 Task FindByStatementNoAsync(long tenantId, string statementNo, CancellationToken cancellationToken = default); + /// + /// 新增账单。 + /// + /// 账单实体。 + /// 取消标记。 Task AddAsync(TenantBillingStatement bill, CancellationToken cancellationToken = default); + /// + /// 更新账单。 + /// + /// 账单实体。 + /// 取消标记。 Task UpdateAsync(TenantBillingStatement bill, CancellationToken cancellationToken = default); + /// + /// 保存变更。 + /// + /// 取消标记。 Task SaveChangesAsync(CancellationToken cancellationToken = default); } diff --git a/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantNotificationRepository.cs b/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantNotificationRepository.cs index 2ee3735..b66093d 100644 --- a/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantNotificationRepository.cs +++ b/src/Domain/TakeoutSaaS.Domain/Tenants/Repositories/ITenantNotificationRepository.cs @@ -11,6 +11,16 @@ namespace TakeoutSaaS.Domain.Tenants.Repositories; /// public interface ITenantNotificationRepository { + /// + /// 查询通知列表,按等级、未读状态与时间范围筛选。 + /// + /// 租户 ID。 + /// 通知等级。 + /// 仅返回未读。 + /// 开始时间(UTC)。 + /// 结束时间(UTC)。 + /// 取消标记。 + /// 通知集合。 Task> SearchAsync( long tenantId, TenantNotificationSeverity? severity, @@ -19,11 +29,32 @@ public interface ITenantNotificationRepository DateTime? to, CancellationToken cancellationToken = default); + /// + /// 按 ID 获取通知。 + /// + /// 租户 ID。 + /// 通知 ID。 + /// 取消标记。 + /// 通知实体或 null。 Task FindByIdAsync(long tenantId, long notificationId, CancellationToken cancellationToken = default); + /// + /// 新增通知。 + /// + /// 通知实体。 + /// 取消标记。 Task AddAsync(TenantNotification notification, CancellationToken cancellationToken = default); + /// + /// 更新通知。 + /// + /// 通知实体。 + /// 取消标记。 Task UpdateAsync(TenantNotification notification, CancellationToken cancellationToken = default); + /// + /// 保存变更。 + /// + /// 取消标记。 Task SaveChangesAsync(CancellationToken cancellationToken = default); } diff --git a/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantAnnouncementReadRepository.cs b/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantAnnouncementReadRepository.cs index 96a1fd3..94b26a2 100644 --- a/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantAnnouncementReadRepository.cs +++ b/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantAnnouncementReadRepository.cs @@ -11,6 +11,7 @@ namespace TakeoutSaaS.Infrastructure.App.Repositories; /// public sealed class EfTenantAnnouncementReadRepository(TakeoutAppDbContext context) : ITenantAnnouncementReadRepository { + /// public Task> GetByAnnouncementAsync(long tenantId, long announcementId, CancellationToken cancellationToken = default) { return context.TenantAnnouncementReads.AsNoTracking() @@ -20,6 +21,7 @@ public sealed class EfTenantAnnouncementReadRepository(TakeoutAppDbContext conte .ContinueWith(t => (IReadOnlyList)t.Result, cancellationToken); } + /// public Task> GetByAnnouncementAsync(long tenantId, IEnumerable announcementIds, long? userId, CancellationToken cancellationToken = default) { var ids = announcementIds.Distinct().ToArray(); @@ -46,17 +48,20 @@ public sealed class EfTenantAnnouncementReadRepository(TakeoutAppDbContext conte .ContinueWith(t => (IReadOnlyList)t.Result, cancellationToken); } + /// public Task FindAsync(long tenantId, long announcementId, long? userId, CancellationToken cancellationToken = default) { return context.TenantAnnouncementReads .FirstOrDefaultAsync(x => x.TenantId == tenantId && x.AnnouncementId == announcementId && x.UserId == userId, cancellationToken); } + /// public Task AddAsync(TenantAnnouncementRead record, CancellationToken cancellationToken = default) { return context.TenantAnnouncementReads.AddAsync(record, cancellationToken).AsTask(); } + /// public Task SaveChangesAsync(CancellationToken cancellationToken = default) { return context.SaveChangesAsync(cancellationToken); diff --git a/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantAnnouncementRepository.cs b/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantAnnouncementRepository.cs index a03d206..404152f 100644 --- a/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantAnnouncementRepository.cs +++ b/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantAnnouncementRepository.cs @@ -12,6 +12,7 @@ namespace TakeoutSaaS.Infrastructure.App.Repositories; /// public sealed class EfTenantAnnouncementRepository(TakeoutAppDbContext context) : ITenantAnnouncementRepository { + /// public Task> SearchAsync( long tenantId, TenantAnnouncementType? type, @@ -45,23 +46,27 @@ public sealed class EfTenantAnnouncementRepository(TakeoutAppDbContext context) .ContinueWith(t => (IReadOnlyList)t.Result, cancellationToken); } + /// public Task FindByIdAsync(long tenantId, long announcementId, CancellationToken cancellationToken = default) { return context.TenantAnnouncements.AsNoTracking() .FirstOrDefaultAsync(x => x.TenantId == tenantId && x.Id == announcementId, cancellationToken); } + /// public Task AddAsync(TenantAnnouncement announcement, CancellationToken cancellationToken = default) { return context.TenantAnnouncements.AddAsync(announcement, cancellationToken).AsTask(); } + /// public Task UpdateAsync(TenantAnnouncement announcement, CancellationToken cancellationToken = default) { context.TenantAnnouncements.Update(announcement); return Task.CompletedTask; } + /// public async Task DeleteAsync(long tenantId, long announcementId, CancellationToken cancellationToken = default) { var entity = await context.TenantAnnouncements.FirstOrDefaultAsync(x => x.TenantId == tenantId && x.Id == announcementId, cancellationToken); @@ -71,6 +76,7 @@ public sealed class EfTenantAnnouncementRepository(TakeoutAppDbContext context) } } + /// public Task SaveChangesAsync(CancellationToken cancellationToken = default) { return context.SaveChangesAsync(cancellationToken); diff --git a/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantBillingRepository.cs b/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantBillingRepository.cs index 23acd1d..3083de5 100644 --- a/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantBillingRepository.cs +++ b/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantBillingRepository.cs @@ -12,6 +12,7 @@ namespace TakeoutSaaS.Infrastructure.App.Repositories; /// public sealed class EfTenantBillingRepository(TakeoutAppDbContext context) : ITenantBillingRepository { + /// public Task> SearchAsync( long tenantId, TenantBillingStatus? status, @@ -43,29 +44,34 @@ public sealed class EfTenantBillingRepository(TakeoutAppDbContext context) : ITe .ContinueWith(t => (IReadOnlyList)t.Result, cancellationToken); } + /// public Task FindByIdAsync(long tenantId, long billingId, CancellationToken cancellationToken = default) { return context.TenantBillingStatements.AsNoTracking() .FirstOrDefaultAsync(x => x.TenantId == tenantId && x.Id == billingId, cancellationToken); } + /// public Task FindByStatementNoAsync(long tenantId, string statementNo, CancellationToken cancellationToken = default) { return context.TenantBillingStatements.AsNoTracking() .FirstOrDefaultAsync(x => x.TenantId == tenantId && x.StatementNo == statementNo, cancellationToken); } + /// public Task AddAsync(TenantBillingStatement bill, CancellationToken cancellationToken = default) { return context.TenantBillingStatements.AddAsync(bill, cancellationToken).AsTask(); } + /// public Task UpdateAsync(TenantBillingStatement bill, CancellationToken cancellationToken = default) { context.TenantBillingStatements.Update(bill); return Task.CompletedTask; } + /// public Task SaveChangesAsync(CancellationToken cancellationToken = default) { return context.SaveChangesAsync(cancellationToken); diff --git a/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantNotificationRepository.cs b/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantNotificationRepository.cs index 1265c25..56cea39 100644 --- a/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantNotificationRepository.cs +++ b/src/Infrastructure/TakeoutSaaS.Infrastructure/App/Repositories/EfTenantNotificationRepository.cs @@ -12,6 +12,7 @@ namespace TakeoutSaaS.Infrastructure.App.Repositories; /// public sealed class EfTenantNotificationRepository(TakeoutAppDbContext context) : ITenantNotificationRepository { + /// public Task> SearchAsync( long tenantId, TenantNotificationSeverity? severity, @@ -49,23 +50,27 @@ public sealed class EfTenantNotificationRepository(TakeoutAppDbContext context) .ContinueWith(t => (IReadOnlyList)t.Result, cancellationToken); } + /// public Task FindByIdAsync(long tenantId, long notificationId, CancellationToken cancellationToken = default) { return context.TenantNotifications .FirstOrDefaultAsync(x => x.TenantId == tenantId && x.Id == notificationId, cancellationToken); } + /// public Task AddAsync(TenantNotification notification, CancellationToken cancellationToken = default) { return context.TenantNotifications.AddAsync(notification, cancellationToken).AsTask(); } + /// public Task UpdateAsync(TenantNotification notification, CancellationToken cancellationToken = default) { context.TenantNotifications.Update(notification); return Task.CompletedTask; } + /// public Task SaveChangesAsync(CancellationToken cancellationToken = default) { return context.SaveChangesAsync(cancellationToken);