Files
TakeoutSaaS.AdminApi/src/Application/TakeoutSaaS.Application/App/Billings/Dto/BillingListDto.cs
MSuMshk 4b53862ded feat: 完成账单管理模块后端功能开发及API优化
核心功能:
- 账单CRUD操作(创建、查询、详情、更新状态、删除)
- 支付记录管理(创建支付、审核支付)
- 批量操作支持(批量更新账单状态)
- 统计分析功能(账单统计、逾期账单查询)
- 导出功能(Excel/PDF/CSV)

API端点 (16个):
- GET /api/admin/v1/billings - 账单列表(分页、筛选、排序)
- POST /api/admin/v1/billings - 创建账单
- GET /api/admin/v1/billings/{id} - 账单详情
- DELETE /api/admin/v1/billings/{id} - 删除账单
- PUT /api/admin/v1/billings/{id}/status - 更新状态
- POST /api/admin/v1/billings/batch/status - 批量更新
- GET /api/admin/v1/billings/{id}/payments - 支付记录
- POST /api/admin/v1/billings/{id}/payments - 创建支付
- PUT /api/admin/v1/billings/payments/{paymentId}/verify - 审核支付
- GET /api/admin/v1/billings/statistics - 统计数据
- GET /api/admin/v1/billings/overdue - 逾期账单
- POST /api/admin/v1/billings/export - 导出账单

架构优化:
- 采用CQRS模式分离读写(MediatR + Dapper + EF Core)
- 完整的领域模型设计(TenantBillingStatement, TenantPayment等)
- FluentValidation请求验证
- 状态机管理账单和支付状态流转

API设计优化 (三项改进):
1. 导出API响应Content-Type改为application/octet-stream
2. 支付审核API添加Approved和Notes可选参数,支持通过/拒绝
3. 移除TenantBillings API中重复的TenantId参数

数据库变更:
- 新增账单相关表及关系
- 支持Snowflake ID主键
- 完整的审计字段支持

🤖 Generated with Claude Code

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2025-12-18 11:24:44 +08:00

115 lines
2.7 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.Tenants.Enums;
using TakeoutSaaS.Shared.Abstractions.Serialization;
namespace TakeoutSaaS.Application.App.Billings.Dto;
/// <summary>
/// 账单列表 DTO管理员端列表展示
/// </summary>
public sealed record BillingListDto
{
/// <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; } = string.Empty;
/// <summary>
/// 订阅 ID可选
/// </summary>
[JsonConverter(typeof(NullableSnowflakeIdJsonConverter))]
public long? SubscriptionId { get; init; }
/// <summary>
/// 账单编号。
/// </summary>
public string StatementNo { get; init; } = string.Empty;
/// <summary>
/// 计费周期开始时间UTC
/// </summary>
public DateTime PeriodStart { get; init; }
/// <summary>
/// 计费周期结束时间UTC
/// </summary>
public DateTime PeriodEnd { get; init; }
/// <summary>
/// 账单类型。
/// </summary>
public BillingType BillingType { get; init; }
/// <summary>
/// 账单状态。
/// </summary>
public TenantBillingStatus Status { 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 decimal TotalAmount { get; init; }
/// <summary>
/// 币种。
/// </summary>
public string Currency { get; init; } = "CNY";
/// <summary>
/// 到期日。
/// </summary>
public DateTime DueDate { get; init; }
/// <summary>
/// 创建时间。
/// </summary>
public DateTime CreatedAt { get; init; }
/// <summary>
/// 更新时间。
/// </summary>
public DateTime? UpdatedAt { get; init; }
/// <summary>
/// 是否逾期。
/// </summary>
public bool IsOverdue { get; init; }
/// <summary>
/// 逾期天数(未逾期为 0
/// </summary>
public int OverdueDays { get; init; }
}