| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687 |
- using System.Globalization;
- namespace Admin.NET.Plugin.AiDOP.Supply;
- /// <summary>
- /// 采购单号生成:类型前缀 + yyyyMMdd + 固定宽度流水(事务内 FOR UPDATE 取号)。
- /// </summary>
- public static class PurOrdNumberGenerator
- {
- public static async Task<string> NextAsync(ISqlSugarClient db, string typePrefix, DateTime sequenceDate, int serialWidth)
- {
- var batch = await NextBatchAsync(db, typePrefix, sequenceDate, serialWidth, 1);
- return batch[0];
- }
- public static async Task<IReadOnlyList<string>> NextBatchAsync(
- ISqlSugarClient db,
- string typePrefix,
- DateTime sequenceDate,
- int serialWidth,
- int count)
- {
- if (count <= 0) throw Oops.Oh("编号数量必须大于 0。");
- if (serialWidth <= 0 || serialWidth > 9) throw Oops.Oh("流水号宽度无效。");
- var prefix = typePrefix.Trim() + sequenceDate.ToString("yyyyMMdd", CultureInfo.InvariantCulture);
- var maxSeq = await db.Ado.GetIntAsync(
- """
- SELECT IFNULL(MAX(CAST(RIGHT(TRIM(PurOrd), @SerialWidth) AS UNSIGNED)), 0)
- FROM PurOrdMaster
- WHERE TRIM(PurOrd) LIKE CONCAT(@Prefix, '%')
- AND CHAR_LENGTH(TRIM(PurOrd)) = CHAR_LENGTH(@Prefix) + @SerialWidth
- FOR UPDATE
- """,
- new SugarParameter("@Prefix", prefix),
- new SugarParameter("@SerialWidth", serialWidth));
- var maxSerial = (int)Math.Pow(10, serialWidth) - 1;
- var result = new List<string>(count);
- for (var i = 1; i <= count; i++)
- {
- var next = maxSeq + i;
- if (next > maxSerial)
- throw Oops.Oh($"当日{typePrefix.Trim()}单号流水已超过 {maxSerial}(前缀 {prefix})");
- result.Add(prefix + next.ToString($"D{serialWidth}", CultureInfo.InvariantCulture));
- }
- return result;
- }
- /// <summary>
- /// PurOrdRctMaster.Receiver:类型前缀 + yyyyMMdd + 固定宽度流水(如 PT202605190001)。
- /// </summary>
- public static async Task<string> NextRctReceiverAsync(
- ISqlSugarClient db,
- string typePrefix,
- string rctType,
- DateTime sequenceDate,
- int serialWidth)
- {
- if (string.IsNullOrWhiteSpace(typePrefix)) throw Oops.Oh("单号前缀无效。");
- if (string.IsNullOrWhiteSpace(rctType)) throw Oops.Oh("收货类型无效。");
- if (serialWidth <= 0 || serialWidth > 9) throw Oops.Oh("流水号宽度无效。");
- var prefix = typePrefix.Trim() + sequenceDate.ToString("yyyyMMdd", CultureInfo.InvariantCulture);
- var maxSeq = await db.Ado.GetIntAsync(
- """
- SELECT IFNULL(MAX(CAST(RIGHT(TRIM(Receiver), @SerialWidth) AS UNSIGNED)), 0)
- FROM PurOrdRctMaster
- WHERE RctType = @RctType
- AND TRIM(Receiver) LIKE CONCAT(@Prefix, '%')
- AND CHAR_LENGTH(TRIM(Receiver)) = CHAR_LENGTH(@Prefix) + @SerialWidth
- FOR UPDATE
- """,
- new SugarParameter("@Prefix", prefix),
- new SugarParameter("@RctType", rctType.Trim()),
- new SugarParameter("@SerialWidth", serialWidth));
- var maxSerial = (int)Math.Pow(10, serialWidth) - 1;
- var next = maxSeq + 1;
- if (next > maxSerial)
- throw Oops.Oh($"当日{typePrefix.Trim()}单号流水已超过 {maxSerial}(前缀 {prefix})");
- return prefix + next.ToString($"D{serialWidth}", CultureInfo.InvariantCulture);
- }
- }
|