You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
81 lines
3.2 KiB
81 lines
3.2 KiB
1 year ago
|
using System;
|
||
|
using System.Threading.Tasks;
|
||
|
using Microsoft.Extensions.Options;
|
||
|
using StackExchange.Redis;
|
||
|
|
||
|
namespace Win.Abp.SerialNumber
|
||
|
{
|
||
|
public class StackExchangeRedisSerialNumberGenerator:ISerialNumberGenerator
|
||
|
{
|
||
|
private readonly ConnectionMultiplexer _redis;
|
||
|
private readonly IDatabase _db;
|
||
|
private readonly string _prefix = string.Empty;
|
||
|
private readonly string _dateTimeFormat = "yyyyMMdd";
|
||
|
private readonly int _numberCount = 6;
|
||
|
private readonly int _step = 1;
|
||
|
private readonly string _separator = string.Empty;
|
||
|
public AbpSerialNumberGeneratorOptions Options { get; }
|
||
|
|
||
|
protected StackExchangeRedisSerialNumberGenerator() { }
|
||
|
|
||
|
public StackExchangeRedisSerialNumberGenerator(IOptions<AbpSerialNumberGeneratorOptions> options)
|
||
|
{
|
||
|
Options = options.Value;
|
||
|
this._prefix = options.Value.GetDefaultPrefix();
|
||
|
this._dateTimeFormat = options.Value.GetDefaultDateTimeFormat();
|
||
|
this._separator = options.Value.GetDefaultSeparator();
|
||
|
this._numberCount = options.Value.GetDefaultNumberCount();
|
||
|
this._step = options.Value.GetDefaultStep();
|
||
|
var redisConnectionString = options.Value.RedisConnectionString;
|
||
|
|
||
|
_redis = ConnectionMultiplexer.Connect(redisConnectionString);
|
||
|
_db = _redis.GetDatabase();
|
||
|
|
||
|
}
|
||
|
|
||
|
public async Task<string> InitAsync(DateTime time, string prefix = null)
|
||
|
{
|
||
|
return await SetAsync(time, prefix);
|
||
|
}
|
||
|
|
||
|
public async Task<string> CreateAsync(DateTime time, string datetimeFormat = null, string prefix = null,
|
||
|
string separator = null, int numberCount = 0, int step = 0)
|
||
|
{
|
||
|
if (prefix == null) prefix = _prefix;
|
||
|
if (separator == null) separator = _separator;
|
||
|
if (datetimeFormat == null) datetimeFormat = _dateTimeFormat;
|
||
|
if (numberCount == 0) numberCount = _numberCount;
|
||
|
if (step == 0) step = _step;
|
||
|
|
||
|
var serial = await GetLastSerialAsync(prefix, time, step);
|
||
|
|
||
|
var serialNumberString = $"{prefix}{separator}" +
|
||
|
$"{time.ToString(datetimeFormat)}{separator}" +
|
||
|
$"{serial.ToString().PadLeft(numberCount, '0')}";
|
||
|
return serialNumberString;
|
||
|
}
|
||
|
|
||
|
public async Task<string> SetAsync(DateTime time, string prefix = null, int serial = 0)
|
||
|
{
|
||
|
var key = GetSerialNumberKey(prefix, time);
|
||
|
await _db.StringSetAsync(key, serial);
|
||
|
return await _db.StringGetAsync(key);
|
||
|
}
|
||
|
|
||
|
|
||
|
private async Task<long> GetLastSerialAsync(string prefix, DateTime time, int step)
|
||
|
{
|
||
|
var key = GetSerialNumberKey(prefix, time);
|
||
|
var serial = await _db.StringIncrementAsync(prefix, step);
|
||
|
Console.WriteLine($"StackExchangeRedis:{key} {serial}");
|
||
|
|
||
|
return serial;
|
||
|
}
|
||
|
|
||
|
private static string GetSerialNumberKey(string prefix, DateTime time)
|
||
|
{
|
||
|
var key = $"{prefix}:{time:yyyyMMdd}";
|
||
|
return key;
|
||
|
}
|
||
|
}
|
||
|
}
|