This commit is contained in:
2026-03-25 14:55:34 +08:00
commit 2c44b3a4b2
131 changed files with 7453 additions and 0 deletions

View File

@@ -0,0 +1,118 @@
using Microsoft.Extensions.Logging;
namespace StopShopping.Services.Implementions;
public class SerialNoGenerator : ISerialNoGenerator
{
public SerialNoGenerator(ILogger<SerialNoGenerator> logger)
{
_logger = logger;
}
private readonly ILogger<SerialNoGenerator> _logger;
private const long START_UTC = 1767196800000; //2026-01-01 00:00:00.000
private const int BITS_CALLBACK = 3;
private const int BITS_SERIAL = 6;
private const long MASK_CALLBACK = ~(-1L << BITS_CALLBACK); //0b_0111
private const long MASK_SERIAL = ~(-1L << BITS_SERIAL);
private readonly object _lockObj = new();
private long _lastUtc = DateTimeOffset.Now.ToUnixTimeMilliseconds();
private long _serial;
private long _callbackSerial;
/// <summary>
/// <list type="table">
/// <item>
/// <term>
/// 0000000
/// </term>
/// <term>
/// 00000000000
/// </term>
/// <term>
/// 00000000000
/// </term>
/// <term>
/// 0000000000
/// </term>
/// </item>
///
/// <item>
/// <term>
/// 符号位1bit
/// </term>
/// </item>
/// <term>
/// 毫秒时间戳56bit
/// </term>
/// <term>
/// 时间回拨标识3bit
/// </term>
/// <term>
/// 毫秒内序号6bit
/// </term>
/// </list>
/// </summary>
/// <returns></returns>
public string GenerateRequestNo()
{
lock (_lockObj)
{
var currUtc = DateTimeOffset.Now.ToUnixTimeMilliseconds();
if (currUtc < _lastUtc) //时间回拨
{
currUtc = _lastUtc;
_callbackSerial = (_callbackSerial + 1) & MASK_CALLBACK;
if (_callbackSerial == 0) //时间回拨标识数据段用完
{
_logger.LogWarning("服务器时间不准,序列号可能重复,请检查!");
}
}
if (currUtc > _lastUtc)
{
_serial = 1;
_callbackSerial = 0;
}
else
{
_serial = (_serial + 1) & MASK_SERIAL;
if (_serial == 0) //毫秒内数据段用完
{
WaitNextMilliSecond(ref currUtc);
_serial = 1;
}
}
_lastUtc = currUtc;
long serial = ((currUtc - START_UTC) << BITS_CALLBACK + BITS_SERIAL)
| (_callbackSerial << BITS_SERIAL)
| _serial;
return string.Format("R{0}", serial);
}
}
public string GenerateProductNo()
{
throw new NotImplementedException();
}
private void WaitNextMilliSecond(ref long curr)
{
while (_lastUtc >= curr)
{
curr = DateTimeOffset.Now.ToUnixTimeMilliseconds();
}
}
public string GenerateRandomPassword()
{
throw new NotImplementedException();
}
}