diff --git a/YLErpDAL/Modules/TradeModule/DocGenerateModule/GuolianContractNoGenerator.cs b/YLErpDAL/Modules/TradeModule/DocGenerateModule/GuolianContractNoGenerator.cs index 7c5b9dad..abfa0d4a 100644 --- a/YLErpDAL/Modules/TradeModule/DocGenerateModule/GuolianContractNoGenerator.cs +++ b/YLErpDAL/Modules/TradeModule/DocGenerateModule/GuolianContractNoGenerator.cs @@ -38,6 +38,7 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule lock (_syncLock) { + // 幂等:如果已生成过确认书编号,直接返回 var existingForTrade = dbContext.trade_contract_r .Where(r => r.TradeId == trade.id && r.Type == ContractTypeEnum.Trade && r.IsValid) .Select(r => r.ContractCode) @@ -48,114 +49,26 @@ namespace YLErp.Modules.TradeModule.DocGenerateModule return existingForTrade; } - var existingCodes = dbContext.trade_contract_r - .Where(d => d.ContractCode.StartsWith(prefix) && d.Type == ContractTypeEnum.Trade && d.IsValid) - .Select(d => d.ContractCode) - .ToList(); - - var existingCodeSet = new HashSet(); - for (var i = 0; i < existingCodes.Count; i++) - { - var code = existingCodes[i]; - if (!string.IsNullOrWhiteSpace(code)) - { - existingCodeSet.Add(code); - } - } + // 通过当天同类交易的 id 排序确定序号(幂等) + var tradeDateStart = tradeDate.Date; + var sameDayTradesCount = dbContext.trade + .Count(t => t.TradeDate >= tradeDateStart + && t.TradeDate < tradeDateStart.AddDays(1) + && t.OpponentRole == trade.OpponentRole + && t.id < trade.id); + var sequenceNo = sameDayTradesCount + 1; if (isClientTrade) { - // 对客交易:GLMS-{clientCode}-{date}-{counter:D2}-{underlyingCode} - var maxNo = 0; - var prefixLen = prefix.Length; - for (var i = 0; i < existingCodes.Count; i++) - { - var code = existingCodes[i]; - if (string.IsNullOrEmpty(code) || code.Length <= prefixLen + 2) - { - continue; - } - - var counterStr = code.Substring(prefixLen, 2); - if (int.TryParse(counterStr, out var n) && n > maxNo) - { - maxNo = n; - } - } - - var nextNo = maxNo + 1; - var contractNo = $"{prefix}{nextNo:D2}-{underlyingCode}"; - while (existingCodeSet.Contains(contractNo)) - { - nextNo++; - contractNo = $"{prefix}{nextNo:D2}-{underlyingCode}"; - } - return contractNo; + return $"{prefix}{sequenceNo:D2}-{underlyingCode}"; } else { - // 非对客交易:GLMS-{clientCode}-{date}-{letter}-{underlyingCode} - // 找当日已有的非对客交易最大字母序号 - var maxLetter = 0; - var prefixLen = prefix.Length; - for (var i = 0; i < existingCodes.Count; i++) - { - var code = existingCodes[i]; - if (string.IsNullOrEmpty(code) || code.Length <= prefixLen + 2) - { - continue; - } - - var rest = code.Substring(prefixLen); - var dashIdx = rest.IndexOf('-'); - if (dashIdx > 0) - { - var letterPart = rest.Substring(0, dashIdx); - if (TryParseLettersToNumber(letterPart, out var ln) && ln > maxLetter) - { - maxLetter = ln; - } - } - } - - var nextLetter = maxLetter + 1; - var contractNo = $"{prefix}{NumberToLetter(nextLetter)}-{underlyingCode}"; - while (existingCodeSet.Contains(contractNo)) - { - nextLetter++; - contractNo = $"{prefix}{NumberToLetter(nextLetter)}-{underlyingCode}"; - } - return contractNo; + return $"{prefix}{NumberToLetter(sequenceNo)}-{underlyingCode}"; } } } - private static bool TryParseLettersToNumber(string letters, out int number) - { - number = 0; - if (string.IsNullOrEmpty(letters)) - { - return false; - } - - for (var i = 0; i < letters.Length; i++) - { - var c = letters[i]; - if (c >= 'a' && c <= 'z') - { - c = (char)(c - 32); - } - else if (c < 'A' || c > 'Z') - { - number = 0; - return false; - } - - number = (number * 26) + (c - 'A' + 1); - } - return true; - } - /// /// 将数字转换为字母序列(1=A, 2=B, 26=Z, 27=AA, 28=AB...) ///