using System; using SqlSugar; using SqlSugar.IOC; namespace ZR.Common; public static class IdUtils { // public static string GetSerialNumber(string code) // { // var vCode = new SugarParameter("@v_code", code); // var vSerialNumber = new SugarParameter("@v_serialnumber", null, true); // vSerialNumber.DbType = System.Data.DbType.String; // //TODO 会抛异常 // DbScoped.SugarScope.GetConnectionScope(0).CopyNew().Ado.UseStoredProcedure() // .GetDataTable("p_get_serialnumber", vCode, vSerialNumber); // // .SqlQuerySingle("p_get_serialnumber", vCode, vSerialNumber); // Console.WriteLine(vSerialNumber.Value.ToString()); // return vSerialNumber.Value.ToString(); // } public static string GetSerialNumber(string code) { var serialNumber = string.Empty; var tmpVal = string.Empty; var resStr = string.Empty; // var sp = string.Empty; // 当前值(加1) int? nextValue = 0; // 目标值(加cnt) int? destValue = 0; // 循环值 int? cycleValue = 0; // 系统类型值 var sysTypeValue = string.Empty; // 类型值 var typeValue = string.Empty; using var db = DbScoped.SugarScope.GetConnectionScope("0"); try { db.Ado.BeginTran(); var codeRule = db.Queryable() .TranLock(DbLockType.Wait) .First(it => it.Code == code); if (codeRule.CurrVal == 0) { nextValue = codeRule.IniVal; } else { nextValue = codeRule.CurrVal + codeRule.Step; } // cycleValue = codeRule.CycleVal; typeValue = codeRule.TypeVal; cycleValue = codeRule.CycleVal ?? 1; switch (codeRule.Type) { case "YYYY": sysTypeValue = DateTime.Now.ToString("yyyy"); break; case "YYYYMM": sysTypeValue = DateTime.Now.ToString("yyyyMM"); break; case "YYYYMMDD": sysTypeValue = DateTime.Now.ToString("yyyyMMdd"); break; default: sysTypeValue = " "; break; } // 循环类型值改变,初始化类型循环 if (string.IsNullOrWhiteSpace(sysTypeValue) != string.IsNullOrWhiteSpace(typeValue)) { typeValue = sysTypeValue; cycleValue = 1; nextValue = codeRule.IniVal; } // 检查是否达到最大值,当达到最大值时抛出异常 if (codeRule.FinishVal != null) { if (codeRule.Cycle != 1) { // 不是循环,有循环不会引发最大值错误 if (codeRule.Step > 0) { if (nextValue > codeRule.FinishVal) { serialNumber = "-1"; } } else { if (nextValue < codeRule.FinishVal) { serialNumber = "-1"; } } } } destValue = nextValue; // 计算取值,如果非循环,数量不足时把剩下的取出返回,如果循环,则循环取 if (codeRule.FinishVal != null) { if (codeRule.Step > 0) { if (destValue > codeRule.FinishVal) { if (codeRule.Cycle == 1) { cycleValue = cycleValue + 1; destValue = codeRule.IniVal; } else { } } } else { if (destValue < codeRule.FinishVal) { if (codeRule.Cycle == 1) { cycleValue = cycleValue + 1; destValue = codeRule.IniVal; } else { } } } } // 生成值字符串,逗号分割 tmpVal = $"{typeValue}{destValue.ToString().PadLeft(codeRule.Width, codeRule.FillChar[0])}"; if (!string.IsNullOrWhiteSpace(codeRule.Prefix)) { tmpVal = $"{codeRule.Prefix}{codeRule.JoinChar ?? string.Empty}{tmpVal}"; } if (!string.IsNullOrWhiteSpace(codeRule.Sufix)) { tmpVal = $"{tmpVal}{codeRule.JoinChar ?? string.Empty}{codeRule.Sufix}"; } resStr = tmpVal; serialNumber = resStr; var foundRows = db.Updateable() .SetColumns(it => new CodeRule { TypeVal = typeValue, CycleVal = cycleValue, CurrVal = destValue, Version = codeRule.Version + 1 }) .Where(it => it.Code == code && it.Version == codeRule.Version) .ExecuteCommand(); if (foundRows != 0) db.Ado.CommitTran(); } catch (Exception e) { // 没有对应更新行,说明被别人更新了,重新计算 serialNumber = "-1"; db.Ado.RollbackTran(); throw; } return serialNumber; } } [SugarTable("base_coderule")] [Tenant("0")] public class CodeRule { /// /// 代码 /// [SugarColumn(IsPrimaryKey = true)] public string Code { get; set; } /// /// 名称 /// public string Name { get; set; } /// /// 类型 /// public string Type { get; set; } /// /// 前缀 /// public string Prefix { get; set; } /// /// 宽度 /// public int Width { get; set; } /// /// 初始值 /// public int IniVal { get; set; } /// /// 增量 /// public int Step { get; set; } /// /// 终止值 /// public int? FinishVal { get; set; } /// /// 循环 /// public int Cycle { get; set; } /// /// 后缀 /// public string Sufix { get; set; } /// /// 分隔符 /// public string JoinChar { get; set; } /// /// 填充符 /// public string FillChar { get; set; } /// /// 类型值 /// public string TypeVal { get; set; } /// /// 循环号 /// public int? CycleVal { get; set; } /// /// 当前值 /// public int? CurrVal { get; set; } /// /// 版本号 /// public int Version { get; set; } }