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}"; } } } }