269 lines
7.6 KiB
C#

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<string>("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<CodeRule>()
.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<CodeRule>()
.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
{
/// <summary>
/// 代码
/// </summary>
[SugarColumn(IsPrimaryKey = true)]
public string Code { get; set; }
/// <summary>
/// 名称
/// </summary>
public string Name { get; set; }
/// <summary>
/// 类型
/// </summary>
public string Type { get; set; }
/// <summary>
/// 前缀
/// </summary>
public string Prefix { get; set; }
/// <summary>
/// 宽度
/// </summary>
public int Width { get; set; }
/// <summary>
/// 初始值
/// </summary>
public int IniVal { get; set; }
/// <summary>
/// 增量
/// </summary>
public int Step { get; set; }
/// <summary>
/// 终止值
/// </summary>
public int? FinishVal { get; set; }
/// <summary>
/// 循环
/// </summary>
public int Cycle { get; set; }
/// <summary>
/// 后缀
/// </summary>
public string Sufix { get; set; }
/// <summary>
/// 分隔符
/// </summary>
public string JoinChar { get; set; }
/// <summary>
/// 填充符
/// </summary>
public string FillChar { get; set; }
/// <summary>
/// 类型值
/// </summary>
public string TypeVal { get; set; }
/// <summary>
/// 循环号
/// </summary>
public int? CycleVal { get; set; }
/// <summary>
/// 当前值
/// </summary>
public int? CurrVal { get; set; }
/// <summary>
/// 版本号
/// </summary>
public int Version { get; set; }
}