Files
TakeoutSaaS.AdminApi/src/Application/TakeoutSaaS.Application/App/Billings/Contracts/BillingDetailDto.cs
MSuMshk 0f900e108d feat(admin): 新增管理员角色、账单、订阅、套餐管理功能
- 新增 AdminRolesController 实现角色 CRUD 和权限管理
- 新增 BillingsController 实现账单查询功能
- 新增 SubscriptionsController 实现订阅管理功能
- 新增 TenantPackagesController 实现套餐管理功能
- 新增租户详情、配额使用、账单列表等查询功能
- 新增 TenantPackage、TenantSubscription 等领域实体
- 新增相关枚举:SubscriptionStatus、TenantPackageType 等
- 更新 appsettings 配置文件
- 更新权限授权策略提供者

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-02 09:11:44 +08:00

198 lines
4.5 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System.Text.Json.Serialization;
using TakeoutSaaS.Domain.Billings.Enums;
using TakeoutSaaS.Shared.Abstractions.Serialization;
namespace TakeoutSaaS.Application.App.Billings.Contracts;
/// <summary>
/// 账单详情 DTO。
/// </summary>
public sealed record BillingDetailDto
{
/// <summary>
/// 账单 ID雪花序列化为字符串
/// </summary>
[JsonConverter(typeof(SnowflakeIdJsonConverter))]
public long Id { get; init; }
/// <summary>
/// 租户 ID雪花序列化为字符串
/// </summary>
[JsonConverter(typeof(SnowflakeIdJsonConverter))]
public long TenantId { get; init; }
/// <summary>
/// 租户名称。
/// </summary>
public string? TenantName { get; init; }
/// <summary>
/// 账单编号。
/// </summary>
public string StatementNo { get; init; } = string.Empty;
/// <summary>
/// 账单类型。
/// </summary>
public TenantBillingType BillingType { get; init; }
/// <summary>
/// 账单周期开始时间。
/// </summary>
public DateTime PeriodStart { get; init; }
/// <summary>
/// 账单周期结束时间。
/// </summary>
public DateTime PeriodEnd { get; init; }
/// <summary>
/// 应付金额。
/// </summary>
public decimal AmountDue { get; init; }
/// <summary>
/// 已付金额。
/// </summary>
public decimal AmountPaid { get; init; }
/// <summary>
/// 折扣金额。
/// </summary>
public decimal DiscountAmount { get; init; }
/// <summary>
/// 税额。
/// </summary>
public decimal TaxAmount { get; init; }
/// <summary>
/// 货币代码。
/// </summary>
public string Currency { get; init; } = "CNY";
/// <summary>
/// 账单状态。
/// </summary>
public TenantBillingStatus Status { get; init; }
/// <summary>
/// 到期日期。
/// </summary>
public DateTime DueDate { get; init; }
/// <summary>
/// 账单明细 JSON。
/// </summary>
public string? LineItemsJson { get; init; }
/// <summary>
/// 备注。
/// </summary>
public string? Notes { get; init; }
/// <summary>
/// 逾期通知时间。
/// </summary>
public DateTime? OverdueNotifiedAt { get; init; }
/// <summary>
/// 提醒发送时间。
/// </summary>
public DateTime? ReminderSentAt { get; init; }
/// <summary>
/// 创建时间。
/// </summary>
public DateTime CreatedAt { get; init; }
/// <summary>
/// 更新时间。
/// </summary>
public DateTime? UpdatedAt { get; init; }
/// <summary>
/// 支付记录列表。
/// </summary>
public IReadOnlyList<PaymentRecordDto> Payments { get; init; } = [];
}
/// <summary>
/// 支付记录 DTO。
/// </summary>
public sealed record PaymentRecordDto
{
/// <summary>
/// 支付记录 ID雪花序列化为字符串
/// </summary>
[JsonConverter(typeof(SnowflakeIdJsonConverter))]
public long Id { get; init; }
/// <summary>
/// 账单 ID雪花序列化为字符串
/// </summary>
[JsonConverter(typeof(SnowflakeIdJsonConverter))]
public long BillingStatementId { get; init; }
/// <summary>
/// 支付金额。
/// </summary>
public decimal Amount { get; init; }
/// <summary>
/// 支付方式。
/// </summary>
public int Method { get; init; }
/// <summary>
/// 支付状态。
/// </summary>
public int Status { get; init; }
/// <summary>
/// 交易号。
/// </summary>
public string? TransactionNo { get; init; }
/// <summary>
/// 支付凭证 URL。
/// </summary>
public string? ProofUrl { get; init; }
/// <summary>
/// 支付时间。
/// </summary>
public DateTime? PaidAt { get; init; }
/// <summary>
/// 备注。
/// </summary>
public string? Notes { get; init; }
/// <summary>
/// 审核人 ID。
/// </summary>
[JsonConverter(typeof(NullableSnowflakeIdJsonConverter))]
public long? VerifiedBy { get; init; }
/// <summary>
/// 审核时间。
/// </summary>
public DateTime? VerifiedAt { get; init; }
/// <summary>
/// 退款原因。
/// </summary>
public string? RefundReason { get; init; }
/// <summary>
/// 退款时间。
/// </summary>
public DateTime? RefundedAt { get; init; }
/// <summary>
/// 创建时间。
/// </summary>
public DateTime CreatedAt { get; init; }
}