我是靠谱客的博主 落后荷花,最近开发中收集的这篇文章主要介绍Caché实现规则编号器,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

背景
以前做护士站的时候,维护床位信息有个给床号编号的问题。为了能批量的按指定规则编号维护床位。当时设想实现一个编号解析器,然后按规则维护编号串就行。然后当时就有C#实现了一套按规则走号的逻辑。来到检验之后碰到各种检验流水号、微生物鉴定号的编号规则,为此改了不少特殊代码。之后重启当年思想,再实现一波Caché的规则编号器,由于接触了json,而json的二维数组就可以很好的表示编号维护意图,因而这次使用大众化的json作为编号维护格式。希望借此一统编号逻辑实现的乱象。

规则定义
约定以JS的JSON格式作为编号描述。JS,C#,M各自实现走号方法。约定以二维数组来描述一个流水号例如:[[“1”,”2”,”3”],[“1”,”2”,”3”],[“a”,”b”,”c”]]
内层数组描述每位数组循环走的数字(可以是任意字符串),从开始一直递增往后取。按十进制走的模式满位进一。
对日期表示的约定$y1 $y2 $y3 $y4表示年的1234位, $M1 $M2表示月的12位, $d1 $d2表示日的12位 $h1 $h2表示时的12位, $m1 $m2表示分钟的12位, $s1 $s2表示秒的12位。

M实现

/// 规则编号器支持类,作为走号基础,非bug不可轻易改动,保证该类的接口性
Class LIS.WS.BLL.DHCLISRuleNo Extends %RegisteredObject
{

// 约定以二维数组来描述一个流水号例如:[["1","2","3"],["1","2","3"],["a","b","c"]]。内层数组描述每位数组循环走的数字(可以是任意字符串),从开始一直递增往后取。按十进制走的模式满位进一。对日期表示的约定$y1 $y2 $y3 $y4表示年的1234位,$M1 $M2表示月的12位,$d1 $d2表示日的12位 $h1 $h2表示时的12位,$m1 $m2表示分钟的12位,$s1 $s2表示秒的12位。

// RuleStr:规则串

// CurNo:当前号,当前号传空返回最小号

// IsDateNoReset:是否日期不重置。1:不重置,否则日期没比对上重新开始号

// 测试初始号

// w ##Class(LIS.WS.BLL.DHCLISRuleNo).GetNextNoByRule("[[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""]]","")

// 测试下一号

// w ##Class(LIS.WS.BLL.DHCLISRuleNo).GetNextNoByRule("[[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""]]","259")

// 测试年效果

// w ##Class(LIS.WS.BLL.DHCLISRuleNo).GetNextNoByRule("[[""0""],[""7""],[""$y3""],[""$y4""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""]]","0719259")

// 测试日期变化是否重置非日期编号(日期编号走号时非日期位数是否重置)

// w ##Class(LIS.WS.BLL.DHCLISRuleNo).GetNextNoByRule("[[""0""],[""7""],[""$d1""],[""$d2""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""]]","0731259")

ClassMethod GetNextNoByRule(RuleStr, CurNo, IsDateNoReset)
{
	//规则串
	s RuleStr=$g(RuleStr)
	//当前号
	s CurNo=$g(CurNo)
	//日期变化是否不重置编号
	s IsDateNoReset=$g(IsDateNoReset)
	
	//分割第二位串
	s RuleStr=$REPLACE(RuleStr,"],[","^")
	//替换双引号
	s RuleStr=$tr(RuleStr,"""","")
	//去掉中括号
	s RuleStr=$tr(RuleStr,"[","")
	//去掉中括号
	s RuleStr=$tr(RuleStr,"]","")
	//存规则的二维数组,方便走位数
	s RuleAll=""
	f i=1:1:$l(RuleStr,"^") d
	.//当前一位数的可走范围
	.s OneRangeStr=$p(RuleStr,"^",i)
	.//存可走范围数组
	.s OneRangeLi=""
	.//解析存可走范围数据
	.f j=1:1:$l(OneRangeStr,",") d
	..s OneRangeLi=OneRangeLi_$lb($p(OneRangeStr,",",j))
	.//按位数存可走数的范围
	.s RuleAll(i)=OneRangeLi
	
	//返回号码
	s RetNo=""
	//空串返回开始号
	i CurNo="" d
	.f i=1:1:$l(RuleStr,"^") d
	..s Index=1
	..//跳过0
	..i (i=$l(RuleStr,"^")),($lg(RuleAll(i),1)="0") d
	...s Index=2
	..s RetNo=RetNo_$lg(RuleAll(i),Index)
	i CurNo="" q ..DealSpecialStr(RetNo)
	
	//检测当前号和规则的长度
	i $l(CurNo)'=$l(RuleStr,"^") q "-1^当前号长度和规则不匹配!"
	//存当前号每位在可选范围的位数
	s IndexList=""
	s Err=""
	
	//每个字符检测维护
	f i=1:1:$l(CurNo) d
	.//当前遍历的字符串
	.s CurChar=$e(CurNo,i,i)
	.//取出当前位数的可选范围
	.s CurRange=RuleAll(i)
	.//检测是否有
	.s HasChar=0
	.//和可选范围比对得到字符的位数
	.f j=1:1:$ll(CurRange) d
	..//相同就是位置
	..i CurChar=$lg(CurRange,j) d
	...//位置存数字
	...s IndexList=IndexList_$lb(j)
	...s HasChar=1
	...//退出检测位置循环
	.//没有匹配上切规则位数为1,考虑日期的规则
	.i (HasChar=0),($ll(CurRange)=1) d
	..//处理可能的日期串
	..s DateRet=..DealDateStr($lg(CurRange,1))
	..//日期匹配
	..i CurChar=DateRet d
	...s IndexList=IndexList_$lb(1)
	...s HasChar=1
	..//日期不匹配
	..e  d
	...//日期变化后不重置
	...i IsDateNoReset="1" d
	....s IndexList=IndexList_$lb(1)
	....s HasChar=1
	...//日期没匹配上获得规则开始号
	...else  if ('$l(RetNo)) d
	....f i=1:1:$l(RuleStr,"^") d
	.....s Index=1
	.....//跳过0
	.....i (i=$l(RuleStr,"^")),($lg(RuleAll(i),1)="0") d
	......s Index=2
	.....s RetNo=RetNo_$lg(RuleAll(i),Index)
	.i HasChar=0 s Err="-1^第"_j_"位不在规则范围内!" q
	//返回日期开始号
	i $l(Err),$l(RetNo) q ..DealSpecialStr(RetNo)
	//返回错误
	i $l(Err) q Err
	//增加量
	s AddNum=1
	
	//逆序按位置增加
	f i=$ll(IndexList):-1:1 d
	.//当前索引加偏移量
	.s curIndex=$lg(IndexList,i)+AddNum
	.//当前可选范围
	.s CurRange=RuleAll(i)
	.//没满位就把偏移量置0,增加完成
	.i curIndex<=$ll(CurRange) d
	..s AddNum=0
	.e  d
	..//否则当前位归最开始,前一个数继续增加位数
	..s curIndex=1
	.//从后往前拼串
	.s RetNo=$lg(CurRange,curIndex)_RetNo
	//最大号不增加
	i AddNum=1 s RetNo=CurNo
	q ..DealSpecialStr(RetNo)
}

/// Creator:      zhanglianzhu
/// CreatDate:    20190601
/// Description:: 
/// Table:        
/// Input:        得到一个规则指定号以后的指定数量的号,没指定号查所有号,没指定数量就是后面99999个
/// Output:       
/// Return:       
/// Others:       
Query QryAllRuleNo(RuleStr, CurNo, Num, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, Sessions, Output RowCount As %String) As %Query(ROWSPEC = "No")
{
}

/// Query的执行方法
/// d ##class(%ResultSet).RunQuery("LIS.WS.BLL.DHCLISRuleNo","QryAllRuleNo","[[""0""],[""7""],[""$y3""],[""$y4""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""],[""0"",""1"",""2"",""3"",""4"",""5"",""6"",""7"",""8"",""9""]]","0719259","","","","","","","","","","","","","","")
ClassMethod QryAllRuleNoExecute(ByRef qHandle As %Binary, RuleStr, CurNo, Num, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, Sessions, Output RowCount As %String) As %Status
{
	//规则串
    s RuleStr=$g(RuleStr)
    //指定号
    s CurNo=$g(CurNo)
    //数量
    s Num=$g(Num)
    //没数量限制最大数量
    i '$l(Num) s Num=99999
 	Set repid=$I(^CacheTemp)
	If $Get(ind)="" Set ind=1
	k ^TMPLIS($zn,repid,$j)
	//没有规则串退出
	i '$l(RuleStr) q $$$OK
	s PreNo=""
	f i=1:1:Num d
	.s CurNo=..GetNextNoByRule(RuleStr,CurNo)
	.d OutputRow
	.i $l(PreNo),PreNo=CurNo q
	.s PreNo=CurNo
	
	k ^TMPLIS($zn,repid,$j)
 	Set qHandle=$lb(0,repid,0)
	Quit $$$OK
	
	
OutputRow
	s Data=$lb(CurNo)
    Set ColFields="CurNo"
 	Set ^CacheTemp(repid,ind)=##Class(LIS.Util.Common).TransListNull(Data,ColFields)
 	Set ind=ind+1
	quit
}

ClassMethod QryAllRuleNoClose(ByRef qHandle As %Binary) As %Status [ PlaceAfter = QryAllRuleNoExecute ]
{
	Set repid=$LIST(qHandle,2)
 	Kill ^CacheTemp(repid)
	Quit $$$OK
}

ClassMethod QryAllRuleNoFetch(ByRef qHandle As %Binary, ByRef Row As %List, ByRef AtEnd As %Integer = 0) As %Status [ PlaceAfter = QryAllRuleNoExecute ]
{
 	Set AtEnd=$LIST(qHandle,1)
 	Set repid=$LIST(qHandle,2)
 	Set ind=$LIST(qHandle,3)
 	Set ind=$o(^CacheTemp(repid,ind))
 	If ind="" {	
 		Set AtEnd=1
 		Set Row=""
 	}
 	Else      {	
 		Set Row=^CacheTemp(repid,ind)
 	}
 	// Save QHandle
 	s qHandle=$lb(AtEnd,repid,ind)
	Quit $$$OK
}

// 处理特殊命令

ClassMethod DealSpecialStr(RuleNo)
{
	s RuleNo=$g(RuleNo)
	//当前日期
	s CurDate=$zd($h,8)
	//当前时间
	s CurTime=$tr($zt($h),":","")
	//日期
	s y1=$e(CurDate,1,1)
	s y2=$e(CurDate,2,2)
	s y3=$e(CurDate,3,3)
	s y4=$e(CurDate,4,4)
	s M1=$e(CurDate,5,5)
	s M2=$e(CurDate,6,6)
	s d1=$e(CurDate,7,7)
	s d2=$e(CurDate,8,8)
	//时间
	s h1=$e(CurTime,1,1)
	s h2=$e(CurTime,2,2)
	s m1=$e(CurTime,3,3)
	s m2=$e(CurTime,4,4)
	s s1=$e(CurTime,5,5)
	s s2=$e(CurTime,6,6)
	s RuleNo=$REPLACE(RuleNo,"$y1",y1)
	s RuleNo=$REPLACE(RuleNo,"$y2",y2)
	s RuleNo=$REPLACE(RuleNo,"$y3",y3)
	s RuleNo=$REPLACE(RuleNo,"$y4",y4)
	
	s RuleNo=$REPLACE(RuleNo,"$M1",M1)
	s RuleNo=$REPLACE(RuleNo,"$M2",M2)
	s RuleNo=$REPLACE(RuleNo,"$d1",d1)
	s RuleNo=$REPLACE(RuleNo,"$d2",d2)
	
	s RuleNo=$REPLACE(RuleNo,"$h1",h1)
	s RuleNo=$REPLACE(RuleNo,"$h2",h2)
	s RuleNo=$REPLACE(RuleNo,"$m1",m1)
	s RuleNo=$REPLACE(RuleNo,"$m2",m2)
	s RuleNo=$REPLACE(RuleNo,"$s1",s1)
	s RuleNo=$REPLACE(RuleNo,"$s2",s2)
	q RuleNo
}

// 处理日期字符串

ClassMethod DealDateStr(RuleNo)
{
	s RuleNo=$g(RuleNo)
	//当前日期
	s CurDate=$zd($h,8)
	//当前时间
	s CurTime=$tr($zt($h),":","")
	//日期
	s y1=$e(CurDate,1,1)
	s y2=$e(CurDate,2,2)
	s y3=$e(CurDate,3,3)
	s y4=$e(CurDate,4,4)
	s M1=$e(CurDate,5,5)
	s M2=$e(CurDate,6,6)
	s d1=$e(CurDate,7,7)
	s d2=$e(CurDate,8,8)
	
	s RuleNo=$REPLACE(RuleNo,"$y1",y1)
	s RuleNo=$REPLACE(RuleNo,"$y2",y2)
	s RuleNo=$REPLACE(RuleNo,"$y3",y3)
	s RuleNo=$REPLACE(RuleNo,"$y4",y4)
	
	s RuleNo=$REPLACE(RuleNo,"$M1",M1)
	s RuleNo=$REPLACE(RuleNo,"$M2",M2)
	s RuleNo=$REPLACE(RuleNo,"$d1",d1)
	s RuleNo=$REPLACE(RuleNo,"$d2",d2)
	
	q RuleNo
}

}

测试效果
在这里插入图片描述

最后

以上就是落后荷花为你收集整理的Caché实现规则编号器的全部内容,希望文章能够帮你解决Caché实现规则编号器所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部