269 lines
7.6 KiB
C#
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; }
|
|
} |