namespace Admin.NET.Plugin.AiDOP.DataPlatform.Sequence;
/// 单号格式化纯函数(可单测,无 DB)。语义对齐 pr_SFM_GetOrdNbr。
public static class NbrSequenceFormatter
{
public static string NormalizeDateFormat(string? dateFormatWithCommas) =>
string.IsNullOrWhiteSpace(dateFormatWithCommas)
? string.Empty
: dateFormatWithCommas.Replace(",", "", StringComparison.Ordinal).Trim();
///
/// 根据规范化后的日期格式(无逗号)计算周期键与拼进号码的日期段。
///
public static (DateTime nbrDate, string nbrDateStr) ResolvePeriod(string normalizedFormat, DateTime now)
{
var fmt = (normalizedFormat ?? string.Empty).Trim();
if (fmt.Length == 0)
return (now.Date, string.Empty);
if (fmt.Equals("YY", StringComparison.OrdinalIgnoreCase))
return (new DateTime(now.Year, 1, 1), now.ToString("yy"));
if (fmt.Equals("YYYY", StringComparison.OrdinalIgnoreCase))
return (new DateTime(now.Year, 1, 1), now.ToString("yyyy"));
if (fmt.Equals("YYMM", StringComparison.OrdinalIgnoreCase))
return (new DateTime(now.Year, now.Month, 1), now.ToString("yyMM"));
if (fmt.Equals("YYYYMM", StringComparison.OrdinalIgnoreCase))
return (new DateTime(now.Year, now.Month, 1), now.ToString("yyyyMM"));
if (fmt.Equals("YYMMDD", StringComparison.OrdinalIgnoreCase))
return (now.Date, now.ToString("yyMMdd"));
// YYYYMMDD 及其他 → 当天 + yyyyMMdd
return (now.Date, now.ToString("yyyyMMdd"));
}
public static int ResolvePadWidth(decimal maxValue)
{
var s = ((long)maxValue).ToString();
return Math.Max(1, s.Length);
}
public static string BuildNumber(string pre1, string pre2, string pre3, string dateStr, long serial, int padWidth)
{
var serialText = serial.ToString();
if (serialText.Length > padWidth)
throw new InvalidOperationException($"单号序号位数超出补零宽度:serial={serial}, width={padWidth}");
return pre1 + pre2 + pre3 + dateStr + serialText.PadLeft(padWidth, '0');
}
public static IReadOnlyList BuildRange(
string pre1, string pre2, string pre3, string dateStr,
long firstSerial, int count, int padWidth)
{
if (count <= 0) throw new ArgumentOutOfRangeException(nameof(count));
var list = new List(count);
for (var i = 0; i < count; i++)
list.Add(BuildNumber(pre1, pre2, pre3, dateStr, firstSerial + i, padWidth));
return list;
}
}