????????對于很多業務系統都需要生成業務流水號,如果訂單號、購采單號等等;而這些業務流水號并不是簡單的一個增長數值,它們很多時候都有一些不同的規則來定義,如不同類型的字母或地區拼音簡寫等。為了更靈活生成這些有規則的業務流水號BeetleX提供對應的組件,接下來簡單介紹一下組件的使用。
????????首先需要通過Nuget引用BeetleX.BNR組件,然后通過以下方法即可以生業務流水號
for (int i = 0; i < 10; i++)
{var number = await BNRFactory.Default.Create("[CN:廣州][D:yyyyMMdd][N:[D:yyyyMMdd]/000000]");Console.WriteLine(number);
}
那個規則看上去好像很復雜,不過先看一下結果輸出是怎樣的
GZ20220520000008
GZ20220520000009
GZ20220520000010
GZ20220520000011
GZ20220520000012
GZ20220520000013
GZ20220520000014
GZ20220520000015
GZ20220520000016
GZ20220520000017
以上流水號規則是[廣州拼間首字母]+[年月日]+[基于年月日為標識的6位自增量]。
????????組件提供的規則是由表達式組成,規則可以根據需求定義多個表達式;表達式的編寫方式是[表達式函數:參數]。接下來介紹一下組件提供的基礎表達式
[CN:中文]
? ? ? ? 返回對應中文信息拼間首字線大寫
[N:標識/填充格式]
? ? ? ? 根據標識來生成對應自增量的數字
[D:日期格式]
? ? ? ? 根據日期輸出當前日期
[S:字符]
????????輸出一個指定的字符
有了上面的描述,接下來定義一個簡單的規則
[CN:廣州][D:yyyyMMdd]
相信對應回上面的表達式應該能知道結果了。
?自定義表達式
????????組件默認提供的表達式有限,但可以根據實際需求來制定一個表達式,可以通過查看一個默認的表達式相信更容易理解
/// <summary>/// {D:yyyyMMdd}/// </summary>[ParameterType("D")]public class DateParameterHandler : IParameterHandler{public Task Execute(StringBuilder sb, string value){sb.Append(DateTime.Now.ToString(value));return Task.CompletedTask;}public BNRFactory Factory{get;set;}}
以上是日期輸出的表達式。
使用Redis自增
????????組件雖然提供了一個自增量的表達式,但存在一個問題就是不同服務之間是無法同步的;通過借助于Reids的自增函數就能實現不同服務中生成唯一的自增數。雖然這個表達式組件集成了,但并沒有直接引入到默認表達式模塊中,需要使用者單獨引入
DefaultRedis.Instance.Host.AddWriteHost("localhost");
BNRFactory.Default.Register("redis", new RedisSequenceParameter(DefaultRedis.Instance));
var number = await BNRFactory.Default.Create("[CN:廣州][redis:[D:yyyy]/000000]");
根據需要注冊一個表達式名稱即可使用。這個Redis的自增表達式實現也非常簡單
public class RedisSequenceParameter : IParameterHandler{public RedisSequenceParameter(Redis.RedisDB db){mRedisDB = db;}private Redis.RedisDB mRedisDB;public?BNRFactory?Factory?{?get;?set;?}public async Task Execute(StringBuilder sb, string value){string[] properties = value.Split('/');StringBuilder key = new StringBuilder();string[] items = RuleAnalysis.Execute(properties[0]);foreach (string p in items){string[] sps = RuleAnalysis.GetProperties(p);IParameterHandler handler = null;if (Factory.Handlers.TryGetValue(sps[0], out handler)){await handler.Execute(key, sps[1]);}}var redisKey = key.ToString();var number = await mRedisDB.Incr(redisKey);sb.Append(number.ToString(properties[1]));}}
示例代碼:
https://github.com/beetlex-io/BeetleX-Samples/tree/master/BeetleX.BNR.App
BeetleX
開源跨平臺通訊框架(支持TLS)
提供HTTP,Websocket,Redis,RPC和服務網關開源組件
https://beetlex-io.com