using System;
namespace XP.ReportEngine.Services
{
///
/// 报告编号生成器 | Report ID generator
/// 生成格式为 RPT-yyyyMMdd-NNN 的唯一报告编号
/// Generates unique report IDs in format: RPT-yyyyMMdd-NNN
/// 线程安全,每日自动重置计数器
/// Thread-safe with daily counter reset
///
public class ReportIdGenerator
{
private readonly object _lock = new();
private int _dailyCounter;
private string _currentDate;
///
/// 构造函数 | Constructor
///
public ReportIdGenerator()
{
_currentDate = DateTime.Now.ToString("yyyyMMdd");
_dailyCounter = 0;
}
///
/// 生成下一个唯一报告编号 | Generate next unique report ID
/// 格式:RPT-yyyyMMdd-NNN(如 RPT-20250101-001)
/// Format: RPT-yyyyMMdd-NNN (e.g., RPT-20250101-001)
///
/// 唯一报告编号 | Unique report ID
public string GenerateNext()
{
lock (_lock)
{
var today = DateTime.Now.ToString("yyyyMMdd");
// 日期变更时重置计数器 | Reset counter when date changes
if (today != _currentDate)
{
_currentDate = today;
_dailyCounter = 0;
}
_dailyCounter++;
return $"RPT-{_currentDate}-{_dailyCounter:D3}";
}
}
///
/// 根据指定时间戳生成报告编号 | Generate report ID with specified timestamp
/// 用于需要指定日期的场景(如补录报告)
/// Used for scenarios requiring specific dates (e.g., backfilling reports)
///
/// 指定的时间戳 | Specified timestamp
/// 唯一报告编号 | Unique report ID
public string GenerateForDate(DateTime timestamp)
{
lock (_lock)
{
var dateStr = timestamp.ToString("yyyyMMdd");
// 如果指定日期与当前日期相同,使用当前计数器
// If specified date matches current date, use current counter
if (dateStr == _currentDate)
{
_dailyCounter++;
return $"RPT-{_currentDate}-{_dailyCounter:D3}";
}
// 如果指定日期与当前日期不同,更新日期并重置计数器
// If specified date differs from current date, update date and reset counter
_currentDate = dateStr;
_dailyCounter = 1;
return $"RPT-{_currentDate}-{_dailyCounter:D3}";
}
}
}
}