NbrSequenceFormatter.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. namespace Admin.NET.Plugin.AiDOP.DataPlatform.Sequence;
  2. /// <summary>单号格式化纯函数(可单测,无 DB)。语义对齐 pr_SFM_GetOrdNbr。</summary>
  3. public static class NbrSequenceFormatter
  4. {
  5. public static string NormalizeDateFormat(string? dateFormatWithCommas) =>
  6. string.IsNullOrWhiteSpace(dateFormatWithCommas)
  7. ? string.Empty
  8. : dateFormatWithCommas.Replace(",", "", StringComparison.Ordinal).Trim();
  9. /// <summary>
  10. /// 根据规范化后的日期格式(无逗号)计算周期键与拼进号码的日期段。
  11. /// </summary>
  12. public static (DateTime nbrDate, string nbrDateStr) ResolvePeriod(string normalizedFormat, DateTime now)
  13. {
  14. var fmt = (normalizedFormat ?? string.Empty).Trim();
  15. if (fmt.Length == 0)
  16. return (now.Date, string.Empty);
  17. if (fmt.Equals("YY", StringComparison.OrdinalIgnoreCase))
  18. return (new DateTime(now.Year, 1, 1), now.ToString("yy"));
  19. if (fmt.Equals("YYYY", StringComparison.OrdinalIgnoreCase))
  20. return (new DateTime(now.Year, 1, 1), now.ToString("yyyy"));
  21. if (fmt.Equals("YYMM", StringComparison.OrdinalIgnoreCase))
  22. return (new DateTime(now.Year, now.Month, 1), now.ToString("yyMM"));
  23. if (fmt.Equals("YYYYMM", StringComparison.OrdinalIgnoreCase))
  24. return (new DateTime(now.Year, now.Month, 1), now.ToString("yyyyMM"));
  25. if (fmt.Equals("YYMMDD", StringComparison.OrdinalIgnoreCase))
  26. return (now.Date, now.ToString("yyMMdd"));
  27. // YYYYMMDD 及其他 → 当天 + yyyyMMdd
  28. return (now.Date, now.ToString("yyyyMMdd"));
  29. }
  30. public static int ResolvePadWidth(decimal maxValue)
  31. {
  32. var s = ((long)maxValue).ToString();
  33. return Math.Max(1, s.Length);
  34. }
  35. public static string BuildNumber(string pre1, string pre2, string pre3, string dateStr, long serial, int padWidth)
  36. {
  37. var serialText = serial.ToString();
  38. if (serialText.Length > padWidth)
  39. throw new InvalidOperationException($"单号序号位数超出补零宽度:serial={serial}, width={padWidth}");
  40. return pre1 + pre2 + pre3 + dateStr + serialText.PadLeft(padWidth, '0');
  41. }
  42. public static IReadOnlyList<string> BuildRange(
  43. string pre1, string pre2, string pre3, string dateStr,
  44. long firstSerial, int count, int padWidth)
  45. {
  46. if (count <= 0) throw new ArgumentOutOfRangeException(nameof(count));
  47. var list = new List<string>(count);
  48. for (var i = 0; i < count; i++)
  49. list.Add(BuildNumber(pre1, pre2, pre3, dateStr, firstSerial + i, padWidth));
  50. return list;
  51. }
  52. }