Files

81 lines
2.9 KiB
C#
Raw Permalink 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;
namespace XP.ReportEngine.Services
{
/// <summary>
/// 报告编号生成器 | Report ID generator
/// 生成格式为 RPT-yyyyMMdd-NNN 的唯一报告编号
/// Generates unique report IDs in format: RPT-yyyyMMdd-NNN
/// 线程安全,每日自动重置计数器
/// Thread-safe with daily counter reset
/// </summary>
public class ReportIdGenerator
{
private readonly object _lock = new();
private int _dailyCounter;
private string _currentDate;
/// <summary>
/// 构造函数 | Constructor
/// </summary>
public ReportIdGenerator()
{
_currentDate = DateTime.Now.ToString("yyyyMMdd");
_dailyCounter = 0;
}
/// <summary>
/// 生成下一个唯一报告编号 | Generate next unique report ID
/// 格式:RPT-yyyyMMdd-NNN(如 RPT-20250101-001
/// Format: RPT-yyyyMMdd-NNN (e.g., RPT-20250101-001)
/// </summary>
/// <returns>唯一报告编号 | Unique report ID</returns>
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}";
}
}
/// <summary>
/// 根据指定时间戳生成报告编号 | Generate report ID with specified timestamp
/// 用于需要指定日期的场景(如补录报告)
/// Used for scenarios requiring specific dates (e.g., backfilling reports)
/// </summary>
/// <param name="timestamp">指定的时间戳 | Specified timestamp</param>
/// <returns>唯一报告编号 | Unique report ID</returns>
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}";
}
}
}
}